HAWQ-1691. Add universal plan used by ORC format
diff --git a/depends/build-all.sh b/depends/build-all.sh
index 17d96b8..627c777 100755
--- a/depends/build-all.sh
+++ b/depends/build-all.sh
@@ -117,10 +117,13 @@
}
echo "Delete headers in ${PREFIX}/include ..."
rm -rf $PREFIX/include/dbcommon
+rm -rf $PREFIX/include/univplan
echo "Done."
echo "Delete libs in ${PREFIX}/lib ..."
rm -rf $PREFIX/lib/libdbcommon*
+rm -rf $PREFIX/lib/libunivplan*
echo "Done."
build dbcommon
+build univplan
diff --git a/depends/univplan/.gitignore b/depends/univplan/.gitignore
new file mode 100644
index 0000000..a9b913a
--- /dev/null
+++ b/depends/univplan/.gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+.cproject
+.project
+.settings
+.pydevproject
+*.pyc
+build/
+CodeCoverageReport/
diff --git a/depends/univplan/CMake/CMakeTestCompileInt64tType.cc b/depends/univplan/CMake/CMakeTestCompileInt64tType.cc
new file mode 100644
index 0000000..ad2fc8e
--- /dev/null
+++ b/depends/univplan/CMake/CMakeTestCompileInt64tType.cc
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <cstdint>
+
+// test if int64_t is typedef to be long long
+
+void test(long long *i) {} // NOLINT
+
+int main() {
+ int64_t i = 0;
+ test(&i);
+ return 0;
+}
diff --git a/depends/univplan/CMake/FindCogapp.cmake b/depends/univplan/CMake/FindCogapp.cmake
new file mode 100644
index 0000000..198c23b
--- /dev/null
+++ b/depends/univplan/CMake/FindCogapp.cmake
@@ -0,0 +1,50 @@
+# locate cogapp and generate source code from template
+#
+# find_package(Cogapp REQUIRED)
+#
+# COGAPP_GENERATE (public function)
+# GENERATED_CODE = Variable to define with generated source files.
+# TEMPLATE = Template used to generate source files.
+#
+# NOTE: The COGAPP_GENERATE macro & add_executable() or add_library()
+# calls only work properly within the same directory.
+#
+
+find_package(PythonInterp REQUIRED)
+
+function(COGAPP_GENERATE GENERATED_CODE)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: COGAPP_GENERATE() called without any template files")
+ return()
+ endif()
+
+ set(${GENERATED_CODE})
+ foreach(FIL ${ARGN})
+ get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
+ file(RELATIVE_PATH FIL_REL ${CMAKE_SOURCE_DIR} ${ABS_FIL})
+
+ get_filename_component(FIL_DIR ${CMAKE_BINARY_DIR}/codegen/${FIL_REL} DIRECTORY)
+ file(MAKE_DIRECTORY ${FIL_DIR})
+
+ get_filename_component(FIL_WE "${CMAKE_BINARY_DIR}/codegen/${FIL_REL}" NAME_WE)
+ get_filename_component(FIL_EXT "${CMAKE_BINARY_DIR}/codegen/${FIL_REL}" EXT)
+
+ set(FIL_OUT "${FIL_DIR}/${FIL_WE}.cg${FIL_EXT}")
+ list(APPEND ${GENERATED_CODE} ${FIL_OUT})
+
+ if(NOT EXISTS ${ABS_FIL})
+ MESSAGE(FATAL_ERROR "file ${ABS_FIL} does not exist")
+ endif()
+
+ add_custom_command(
+ OUTPUT ${FIL_OUT}
+ COMMAND ${PYTHON_EXECUTABLE}
+ ARGS -m cogapp -d -o ${FIL_OUT} ${ABS_FIL}
+ DEPENDS ${ABS_FIL}
+ COMMENT "Running cog on ${FIL}"
+ VERBATIM )
+ endforeach()
+
+ set_source_files_properties(${${GENERATED_CODE}} PROPERTIES GENERATED TRUE)
+ set(${GENERATED_CODE} ${${GENERATED_CODE}} PARENT_SCOPE)
+endfunction()
\ No newline at end of file
diff --git a/depends/univplan/CMake/FindGFlags.cmake b/depends/univplan/CMake/FindGFlags.cmake
new file mode 100644
index 0000000..f93c571
--- /dev/null
+++ b/depends/univplan/CMake/FindGFlags.cmake
@@ -0,0 +1,48 @@
+# - Try to find GFLAGS
+#
+# The following variables are optionally searched for defaults
+# GFLAGS_ROOT_DIR: Base directory where all GFLAGS components are found
+#
+# The following are set after configuration is done:
+# GFLAGS_FOUND
+# GFLAGS_INCLUDE_DIRS
+# GFLAGS_LIBRARIES
+# GFLAGS_LIBRARYRARY_DIRS
+
+include(FindPackageHandleStandardArgs)
+
+set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags")
+
+# We are testing only a couple of files in the include directories
+if(WIN32)
+ find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
+ PATHS ${GFLAGS_ROOT_DIR}/src/windows)
+else()
+ find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
+ PATHS ${GFLAGS_ROOT_DIR})
+endif()
+
+if(MSVC)
+ find_library(GFLAGS_LIBRARY_RELEASE
+ NAMES libgflags
+ PATHS ${GFLAGS_ROOT_DIR}
+ PATH_SUFFIXES Release)
+
+ find_library(GFLAGS_LIBRARY_DEBUG
+ NAMES libgflags-debug
+ PATHS ${GFLAGS_ROOT_DIR}
+ PATH_SUFFIXES Debug)
+
+ set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
+else()
+ find_library(GFLAGS_LIBRARY gflags)
+endif()
+
+find_package_handle_standard_args(GFLAGS DEFAULT_MSG
+ GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY)
+
+
+if(GFLAGS_FOUND)
+ set(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR})
+ set(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY})
+endif()
diff --git a/depends/univplan/CMake/FindGlog.cmake b/depends/univplan/CMake/FindGlog.cmake
new file mode 100644
index 0000000..d9f0ee0
--- /dev/null
+++ b/depends/univplan/CMake/FindGlog.cmake
@@ -0,0 +1,49 @@
+
+# - Try to find Glog
+#
+# The following variables are optionally searched for defaults
+# GLOG_ROOT_DIR: Base directory where all GLOG components are found
+#
+# The following are set after configuration is done:
+# GLOG_FOUND
+# GLOG_INCLUDE_DIRS
+# GLOG_LIBRARIES
+# GLOG_LIBRARYRARY_DIRS
+
+include(FindPackageHandleStandardArgs)
+
+set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
+
+if(WIN32)
+ find_path(GLOG_INCLUDE_DIR glog/logging.h
+ PATHS ${GLOG_ROOT_DIR}/src/windows)
+else()
+ find_path(GLOG_INCLUDE_DIR glog/logging.h
+ PATHS ${GLOG_ROOT_DIR})
+endif()
+
+if(MSVC)
+ find_library(GLOG_LIBRARY_RELEASE libglog_static
+ PATHS ${GLOG_ROOT_DIR}
+ PATH_SUFFIXES Release)
+
+ find_library(GLOG_LIBRARY_DEBUG libglog_static
+ PATHS ${GLOG_ROOT_DIR}
+ PATH_SUFFIXES Debug)
+
+ set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG})
+else()
+ find_library(GLOG_LIBRARY glog
+ PATHS ${GLOG_ROOT_DIR}
+ PATH_SUFFIXES
+ lib
+ lib64)
+endif()
+
+find_package_handle_standard_args(GLOG DEFAULT_MSG
+ GLOG_INCLUDE_DIR GLOG_LIBRARY)
+
+if(GLOG_FOUND)
+ set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
+ set(GLOG_LIBRARIES ${GLOG_LIBRARY})
+endif()
\ No newline at end of file
diff --git a/depends/univplan/CMake/FindJSON.cmake b/depends/univplan/CMake/FindJSON.cmake
new file mode 100644
index 0000000..a334948
--- /dev/null
+++ b/depends/univplan/CMake/FindJSON.cmake
@@ -0,0 +1,38 @@
+# - Find json
+# Find the native JSON headers and libraries.
+#
+# JSON_INCLUDE_DIRS - where to find json/json.h, etc.
+# JSON_LIBRARIES - List of libraries when using json.
+# JSON_FOUND - True if json found.
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Look for the header file.
+find_path(JSON_INCLUDE_DIR NAMES json/json.h)
+mark_as_advanced(JSON_INCLUDE_DIR)
+
+# Look for the library (sorted from most current/relevant entry to least).
+find_library(JSON_LIBRARY NAMES jsoncpp
+)
+mark_as_advanced(JSON_LIBRARY)
+
+# handle the QUIETLY and REQUIRED arguments and set JSON_FOUND to TRUE if
+# all listed variables are TRUE
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(JSON DEFAULT_MSG JSON_INCLUDE_DIR JSON_LIBRARY)
+
+if(JSON_FOUND)
+ set(JSON_LIBRARIES ${JSON_LIBRARY})
+ set(JSON_INCLUDE_DIRS ${JSON_INCLUDE_DIR})
+endif()
diff --git a/depends/univplan/CMake/FindSnappy.cmake b/depends/univplan/CMake/FindSnappy.cmake
new file mode 100644
index 0000000..623d2d7
--- /dev/null
+++ b/depends/univplan/CMake/FindSnappy.cmake
@@ -0,0 +1,30 @@
+# Variables used by this module, they can change the default behaviour and need
+# to be set before calling find_package:
+#
+# SNAPPY_ROOT_DIR Set this variable to the root installation of
+# Snappy if the module has problems finding
+# the proper installation path.
+#
+# Variables defined by this module:
+#
+# SNAPPY_FOUND System has Snappy libs/headers
+# SNAPPY_LIBRARIES The Snappy libraries
+# SNAPPY_INCLUDE_DIR The location of Snappy headers
+
+find_path(SNAPPY_INCLUDE_DIR
+ NAMES snappy.h
+ HINTS ${SNAPPY_ROOT_DIR}/include)
+
+find_library(SNAPPY_LIBRARIES
+ NAMES snappy
+ HINTS ${SNAPPY_ROOT_DIR}/lib)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Snappy DEFAULT_MSG
+ SNAPPY_LIBRARIES
+ SNAPPY_INCLUDE_DIR)
+
+mark_as_advanced(
+ SNAPPY_ROOT_DIR
+ SNAPPY_LIBRARIES
+ SNAPPY_INCLUDE_DIR)
diff --git a/depends/univplan/CMake/Functions.cmake b/depends/univplan/CMake/Functions.cmake
new file mode 100644
index 0000000..a771b60
--- /dev/null
+++ b/depends/univplan/CMake/Functions.cmake
@@ -0,0 +1,46 @@
+FUNCTION(AUTO_SOURCES RETURN_VALUE PATTERN SOURCE_SUBDIRS)
+
+ IF ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
+ SET(PATH ".")
+ IF (${ARGC} EQUAL 4)
+ LIST(GET ARGV 3 PATH)
+ ENDIF ()
+ ENDIF()
+
+ IF ("${SOURCE_SUBDIRS}" STREQUAL "RECURSE")
+ UNSET(${RETURN_VALUE})
+ FILE(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
+ LIST(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
+
+ FILE(GLOB SUBDIRS RELATIVE ${PATH} ${PATH}/*)
+
+ FOREACH(DIR ${SUBDIRS})
+ IF (IS_DIRECTORY ${PATH}/${DIR})
+ IF (NOT "${DIR}" STREQUAL "CMAKEFILES")
+ FILE(GLOB_RECURSE SUBDIR_FILES "${PATH}/${DIR}/${PATTERN}")
+ LIST(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
+ ENDIF()
+ ENDIF()
+ ENDFOREACH()
+ ELSE ()
+ FILE(GLOB ${RETURN_VALUE} "${PATTERN}")
+
+ FOREACH (PATH ${SOURCE_SUBDIRS})
+ FILE(GLOB SUBDIR_FILES "${PATH}/${PATTERN}")
+ LIST(APPEND ${RETURN_VALUE} ${SUBDIR_FILES})
+ ENDFOREACH(PATH ${SOURCE_SUBDIRS})
+ ENDIF ()
+
+ IF (${FILTER_OUT})
+ LIST(REMOVE_ITEM ${RETURN_VALUE} ${FILTER_OUT})
+ ENDIF()
+
+ SET(${RETURN_VALUE} ${${RETURN_VALUE}} PARENT_SCOPE)
+ENDFUNCTION(AUTO_SOURCES)
+
+FUNCTION(CONTAINS_STRING FILE SEARCH RETURN_VALUE)
+ FILE(STRINGS ${FILE} FILE_CONTENTS REGEX ".*${SEARCH}.*")
+ IF (FILE_CONTENTS)
+ SET(${RETURN_VALUE} TRUE PARENT_SCOPE)
+ ENDIF()
+ENDFUNCTION(CONTAINS_STRING)
diff --git a/depends/univplan/CMake/Options.cmake b/depends/univplan/CMake/Options.cmake
new file mode 100644
index 0000000..36841ea
--- /dev/null
+++ b/depends/univplan/CMake/Options.cmake
@@ -0,0 +1,71 @@
+##############################################################################
+# In this file we handle all env and customer's settings
+##############################################################################
+
+##############################################################################
+# Setup build and dependencies information
+##############################################################################
+SET(DEPENDENCY_INSTALL_PREFIX "/opt/dependency")
+IF($ENV{DEPENDENCY_INSTALL_PREFIX})
+ SET(DEPENDENCY_INSTALL_PREFIX $ENV{DEPENDENCY_INSTALL_PREFIX})
+ENDIF()
+
+SET(DEPENDENCY_DIST_PACKAGE_NAME "dependency-dist-package.tar.gz")
+IF($ENV{DEPENDENCY_DIST_PACKAGE_NAME})
+ SET(DEPENDENCY_DIST_PACKAGE_NAME $ENV{DEPENDENCY_DIST_PACKAGE_NAME})
+ENDIF()
+
+SET(CMAKE_PREFIX_PATH "${DEPENDENCY_INSTALL_PREFIX}" ${CMAKE_PREFIX_PATH})
+SET(CMAKE_PREFIX_PATH "${DEPENDENCY_INSTALL_PREFIX}/package" ${CMAKE_PREFIX_PATH})
+SET(CMAKE_PREFIX_PATH "${DEPENDENCY_INSTALL_PREFIX}/tools" ${CMAKE_PREFIX_PATH})
+
+SET(DEPENDENCY_LIBRARY_PATH "${DEPENDENCY_INSTALL_PREFIX}/package/lib:${DEPENDENCY_LIBRARY_PATH}")
+SET(DEPENDENCY_LIBRARY_PATH "${DEPENDENCY_INSTALL_PREFIX}/package/lib64:${DEPENDENCY_LIBRARY_PATH}")
+
+##############################################################################
+# Setup build flags
+##############################################################################
+OPTION(ENABLE_COVERAGE "enable code coverage." OFF)
+
+IF(NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+IF(ENABLE_COVERAGE STREQUAL ON)
+ INCLUDE(CodeCoverage)
+ENDIF(ENABLE_COVERAGE STREQUAL ON)
+
+IF(CMAKE_BUILD_TYPE MATCHES Debug)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
+ENDIF()
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fno-omit-frame-pointer -fno-strict-aliasing")
+
+IF(ENABLE_AVX STREQUAL ON)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx -mno-avx2")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DAVX_OPT")
+ELSE()
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-avx -mno-avx2")
+ENDIF()
+
+#c++11 is needed to provide thread saft singleton implementation.
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-deprecated-register")
+#-Rpass-missed=loop-vectorize -Wall -Wconversion
+
+IF(CMAKE_COMPILER_IS_CLANG)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-limit-debug-info -stdlib=libc++ -DUSE_CLANG")
+ IF(OS_LINUX)
+ SET(CLANG_LDFLAGS "-lc++abi -lc++" ${CLANG_LDFLAGS})
+ ENDIF(OS_LINUX)
+ENDIF(CMAKE_COMPILER_IS_CLANG)
+
+TRY_COMPILE(INT64T_EQUAL_LONGLONG
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeTestCompileInt64tType.cc
+ OUTPUT_VARIABLE OUTPUT)
+
+IF(INT64T_EQUAL_LONGLONG)
+ MESSAGE(STATUS "Checking whether int64_t is typedef to long long -- yes")
+ELSE(INT64T_EQUAL_LONGLONG)
+ MESSAGE(STATUS "Checking whether int64_t is typedef to long long -- no")
+ENDIF(INT64T_EQUAL_LONGLONG)
diff --git a/depends/univplan/CMake/Platform.cmake b/depends/univplan/CMake/Platform.cmake
new file mode 100644
index 0000000..1ee0238
--- /dev/null
+++ b/depends/univplan/CMake/Platform.cmake
@@ -0,0 +1,47 @@
+IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ SET(OS_LINUX true CACHE INTERNAL "Linux operating system")
+ELSEIF(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ SET(OS_MACOSX true CACHE INTERNAL "Mac Darwin operating system")
+ELSE(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ MESSAGE(FATAL_ERROR "Unsupported OS: \"${CMAKE_SYSTEM_NAME}\"")
+ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+
+IF(CMAKE_COMPILER_IS_GNUCXX)
+ EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE COMPILER_OUTPUT)
+
+ STRING(REGEX MATCH "[0-9]\\.[0-9]\\.[0-9]" GCC_COMPILER_VERSION ${COMPILER_OUTPUT})
+ STRING(REGEX MATCHALL "[0-9]" GCC_COMPILER_VERSION ${GCC_COMPILER_VERSION})
+
+ LIST(LENGTH GCC_COMPILER_VERSION GCC_COMPILER_VERSION_LEN)
+ IF (NOT 3 EQUAL ${GCC_COMPILER_VERSION_LEN})
+ MESSAGE(FATAL_ERROR "Cannot get gcc version from \"${COMPILER_OUTPUT}\"")
+ ENDIF(NOT 3 EQUAL ${GCC_COMPILER_VERSION_LEN})
+
+ LIST(GET GCC_COMPILER_VERSION 0 GCC_COMPILER_VERSION_MAJOR)
+ LIST(GET GCC_COMPILER_VERSION 1 GCC_COMPILER_VERSION_MINOR)
+ LIST(GET GCC_COMPILER_VERSION 2 GCC_COMPILER_VERSION_PATCH)
+
+ SET(GCC_COMPILER_VERSION_MAJOR ${GCC_COMPILER_VERSION_MAJOR} CACHE INTERNAL "gcc major version")
+ SET(GCC_COMPILER_VERSION_MINOR ${GCC_COMPILER_VERSION_MINOR} CACHE INTERNAL "gcc minor version")
+ SET(GCC_COMPILER_VERSION_PATCH ${GCC_COMPILER_VERSION_PATCH} CACHE INTERNAL "gcc patch version")
+
+ MESSAGE(STATUS "checking compiler: GCC (${GCC_COMPILER_VERSION_MAJOR}.${GCC_COMPILER_VERSION_MINOR}.${GCC_COMPILER_VERSION_PATCH})")
+ELSE(CMAKE_COMPILER_IS_GNUCXX)
+ EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE COMPILER_OUTPUT)
+ IF(COMPILER_OUTPUT MATCHES "clang")
+ SET(CMAKE_COMPILER_IS_CLANG true CACHE INTERNAL "using clang as compiler")
+ MESSAGE(STATUS "checking compiler: CLANG")
+ ELSE(COMPILER_OUTPUT MATCHES "clang")
+ MESSAGE(FATAL_ERROR "Unsupported compiler: \"${CMAKE_CXX_COMPILER}\"")
+ ENDIF(COMPILER_OUTPUT MATCHES "clang")
+ENDIF(CMAKE_COMPILER_IS_GNUCXX)
+
+INCLUDE (TestBigEndian)
+TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN)
+ message(STATUS "BIG_ENDIAN")
+ ADD_DEFINITIONS(-DIS_BIG_ENDIAN)
+else()
+ message(STATUS "LITTLE_ENDIAN")
+ ADD_DEFINITIONS(-DIS_LITTLE_ENDIAN)
+endif()
diff --git a/depends/univplan/CMakeLists.txt b/depends/univplan/CMakeLists.txt
new file mode 100644
index 0000000..f25ad2c
--- /dev/null
+++ b/depends/univplan/CMakeLists.txt
@@ -0,0 +1,28 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(univplan)
+
+##############################################################################
+# General CMake initialization
+##############################################################################
+SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})
+SET(CMAKE_VERBOSE_MAKEFILE OFF CACHE STRING "Verbose build." FORCE)
+
+IF(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
+ MESSAGE(FATAL_ERROR "cannot build the project in the source directory! Out-of-source build is enforced!")
+ENDIF()
+
+##############################################################################
+# Import env, customer settings and utilities
+##############################################################################
+INCLUDE(Functions)
+INCLUDE(Platform)
+INCLUDE(Options)
+
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(test)
+
+ADD_CUSTOM_TARGET(coverage
+ COMMAND make resetcoverage
+ COMMAND make -j8 unittest
+ COMMAND make ucoverage
+ COMMENT "Run all unit tests and get coverage...")
diff --git a/depends/univplan/README b/depends/univplan/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/depends/univplan/README
diff --git a/depends/univplan/bootstrap b/depends/univplan/bootstrap
new file mode 100755
index 0000000..36fd66c
--- /dev/null
+++ b/depends/univplan/bootstrap
@@ -0,0 +1,109 @@
+#!/bin/sh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+die() {
+ echo "$@" 1>&2 ; exit 1
+}
+
+arg ()
+{
+ echo "$1" | sed "s/^${2-[^=]*=}//"
+}
+
+# Detect directory information.
+source_dir=`cd "\`dirname \"$0\"\`";pwd`
+binary_dir=`pwd`
+
+# Choose the default install prefix.
+default_prefix="/opt/dependency/package"
+
+# Display bootstrap usage
+usage() {
+echo '
+Usage: '"$0"' [<options>]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --help print this message
+ --prefix=PREFIX install files in tree rooted at PREFIX
+ ['"${default_prefix}"']
+ --enable-coverage enable code coverage, must be used together with --enable-debug
+ --enable-debug enable debug build
+ --enable-avx enable avx for vector instruction optimization
+'
+ exit 10
+}
+
+# Parse arguments
+prefix_dir="${default_prefix}"
+build_type="Release"
+enable_coverage="OFF"
+enable_avx="ON"
+while test $# != 0; do
+ case "$1" in
+ --prefix=*) dir=`arg "$1"`
+ prefix_dir="$dir";;
+ --enable-coverage) enable_coverage="ON"
+ build_type="Debug";;
+ --enable-debug) build_type="Debug";;
+ --enable-avx=*) avx=`arg "$1"`
+ enable_avx="$avx";;
+ --help) usage ;;
+ *) die "Unknown option: $1" ;;
+ esac
+ shift
+done
+
+if [ ${source_dir} = ${binary_dir} ]; then
+ die "cannot build the project in the source directory! Out-of-source build is enforced!"
+fi
+
+enable_avx_upper=`echo "${enable_avx}" | tr [a-z] [A-Z]`
+if [ ${enable_avx_upper} != "ON" ] && [ ${enable_avx_upper} != "OFF" ]; then
+ die "unknown value for option enable-avx: ${enable_avx}, valid options are: on and off"
+fi
+
+# Check clang compiler
+if [[ x"${CC}" = x"" ]]; then
+ CC=gcc
+fi
+
+if [[ x"${CXX}" = x"" ]]; then
+ CXX=g++
+fi
+
+c_compiler=`which ${CC}`
+cxx_compiler=`which ${CXX}`
+cmake=`which cmake`
+
+if [ ! -x ${c_compiler} ]; then
+ die "cannot found c compiler"
+fi
+
+if [ ! -x ${cxx_compiler} ]; then
+ die "cannot found c++ compiler"
+fi
+
+if [ ! -x ${cmake} ]; then
+ die "cannot found cmake"
+fi
+
+# Configure
+${cmake} -DCMAKE_BUILD_TYPE=${build_type} -DCMAKE_INSTALL_PREFIX=${prefix_dir} -DCMAKE_C_COMPILER=${c_compiler} -DCMAKE_CXX_COMPILER=${cxx_compiler} -DENABLE_COVERAGE=${enable_coverage} -DENABLE_AVX=${enable_avx_upper} ${source_dir} || die "failed to configure the project"
+
+echo 'bootstrap success. Run "make" to build.'
diff --git a/depends/univplan/src/CMakeLists.txt b/depends/univplan/src/CMakeLists.txt
new file mode 100644
index 0000000..f53e3a7
--- /dev/null
+++ b/depends/univplan/src/CMakeLists.txt
@@ -0,0 +1,77 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(univplan)
+
+FIND_PACKAGE(Protobuf REQUIRED)
+
+SET(univplan_VERSION_MAJOR 0)
+SET(univplan_VERSION_MINOR 1)
+SET(univplan_VERSION_PATCH 0)
+SET(univplan_VERSION_API 1)
+set(CMAKE_MACOSX_RPATH 1)
+
+SET(univplan_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+SET(univplan_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/univplan)
+SET(univplan_proto_DIR ${univplan_SRC_DIR}/proto)
+
+file(GLOB proto_files "${univplan_SRC_DIR}/proto/*.proto")
+set(proto_SRC_DIR ${CMAKE_BINARY_DIR}/src/univplan/proto)
+set(UNIVPLAN_PROTO_HDRS
+ ${proto_SRC_DIR}/universal-plan.pb.h
+ ${proto_SRC_DIR}/universal-plan-catalog.pb.h
+ ${proto_SRC_DIR}/universal-plan-expr.pb.h
+)
+set(UNIVPLAN_PROTO_SRCS
+ ${proto_SRC_DIR}/universal-plan.pb.cc
+ ${proto_SRC_DIR}/universal-plan-catalog.pb.cc
+ ${proto_SRC_DIR}/universal-plan-expr.pb.cc
+)
+file(MAKE_DIRECTORY ${proto_SRC_DIR})
+add_custom_command(
+ OUTPUT ${UNIVPLAN_PROTO_SRCS} ${UNIVPLAN_PROTO_HDRS}
+ COMMAND ${Protobuf_PROTOC_EXECUTABLE}
+ ARGS --cpp_out ${CMAKE_BINARY_DIR}/src -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_files}
+ DEPENDS "${proto_files}"
+ )
+
+AUTO_SOURCES(univplan_files "*.cc" "RECURSE" "${univplan_SRC_DIR}")
+LIST(APPEND univplan_SOURCES ${univplan_files})
+
+AUTO_SOURCES(univplanbuilder_HEADER "*.h" "${univplan_SRC_DIR}/univplanbuilder")
+AUTO_SOURCES(common_HEADER "*.h" "${univplan_SRC_DIR}/common")
+AUTO_SOURCES(cwrapper_HEADER "*.h" "${univplan_SRC_DIR}/cwrapper")
+AUTO_SOURCES(minmax_HEADER "*.h" "${univplan_SRC_DIR}/minmax")
+AUTO_SOURCES(testutil_HEADER "*.h" "${univplan_SRC_DIR}/testutil")
+
+INCLUDE_DIRECTORIES(${univplan_ROOT_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/src)
+INCLUDE_DIRECTORIES(${DEPENDENCY_INSTALL_PREFIX}/package/include)
+
+LINK_DIRECTORIES(${DEPENDENCY_INSTALL_PREFIX}/package/lib)
+
+
+ADD_LIBRARY(univplan-shared SHARED
+ ${UNIVPLAN_PROTO_HDRS}
+ ${UNIVPLAN_PROTO_SRCS}
+ ${univplan_SOURCES}
+ )
+# ADD_LIBRARY(univplan-static STATIC ${univplan_SOURCES} ${UNIVPLAN_PROTO_SRCS} ${UNIVPLAN_PROTO_HDRS})
+
+SET_TARGET_PROPERTIES(univplan-shared PROPERTIES OUTPUT_NAME "univplan")
+# SET_TARGET_PROPERTIES(univplan-static PROPERTIES OUTPUT_NAME "univplan")
+
+target_link_libraries(univplan-shared ${CLANG_LDFLAGS} dbcommon glog protobuf pthread)
+# target_link_libraries(univplan-static ${CLANG_LDFLAGS} dbcommon glog protobuf pthread)
+
+INSTALL(TARGETS univplan-shared
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib)
+
+INSTALL(FILES ${univplanbuilder_HEADER} DESTINATION include/univplan/univplanbuilder)
+INSTALL(FILES ${common_HEADER} DESTINATION include/univplan/common)
+INSTALL(FILES ${cwrapper_HEADER} DESTINATION include/univplan/cwrapper)
+INSTALL(FILES ${minmax_HEADER} DESTINATION include/univplan/minmax)
+INSTALL(FILES ${testutil_HEADER} DESTINATION include/univplan/testutil)
+INSTALL(FILES ${UNIVPLAN_PROTO_HDRS} DESTINATION include/univplan/proto)
+
+SET(univplan_ROOT_DIR ${univplan_ROOT_DIR} PARENT_SCOPE)
diff --git a/depends/univplan/src/univplan/common/expression.cc b/depends/univplan/src/univplan/common/expression.cc
new file mode 100644
index 0000000..974bf39
--- /dev/null
+++ b/depends/univplan/src/univplan/common/expression.cc
@@ -0,0 +1,742 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/common/expression.h"
+
+#include <algorithm>
+
+#include "dbcommon/common/tuple-batch.h"
+#include "dbcommon/common/vector/fixed-length-vector.h"
+#include "dbcommon/common/vector/list-vector.h"
+#include "dbcommon/common/vector/struct-vector.h"
+#include "dbcommon/common/vector/variable-length-vector.h"
+#include "dbcommon/function/func-kind.cg.h"
+#include "dbcommon/log/logger.h"
+#include "dbcommon/type/array.h"
+#include "dbcommon/type/type-util.h"
+
+namespace univplan {
+
+dbcommon::SelectList *ExprState::convertSelectList(const dbcommon::Datum &d,
+ ExprContext *context) {
+ dbcommon::Object *obj = dbcommon::DatumGetValue<dbcommon::Object *>(d);
+ dbcommon::SelectList *sel = nullptr;
+ dbcommon::BooleanVector *vec = nullptr;
+ dbcommon::Scalar *val = nullptr;
+
+ if ((sel = dynamic_cast<dbcommon::SelectList *>(obj)) == nullptr) {
+ if (convertedSelectlist == nullptr)
+ convertedSelectlist.reset(new dbcommon::SelectList);
+ sel = convertedSelectlist.get();
+ if ((vec = dynamic_cast<dbcommon::BooleanVector *>(obj)) != nullptr) {
+ sel->fromVector(vec);
+ } else if ((val = dynamic_cast<dbcommon::Scalar *>(obj)) != nullptr) {
+ sel->clear();
+ if (val->getBoolValue()) {
+ auto size = context->getNumOfRows();
+ sel->resize(size);
+ for (auto i = 0; i < size; i++) (*sel)[i] = i;
+ }
+ } else {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "Supposed to be SelectList or BooleanVector or Const");
+ }
+ }
+ return sel;
+}
+
+ListExprState::ListExprState(const univplan::UnivPlanExprPolyList *exprs) {
+ for (int i = 0; i < exprs->size(); ++i) {
+ args.push_back(InitExpr(&exprs->Get(i)));
+ }
+}
+
+dbcommon::Datum ListExprState::calc(ExprContext *context) {
+ dbcommon::SelectList *result = nullptr;
+
+ for (ExprState::uptr &e : args) {
+ dbcommon::Datum d = e->calc(context);
+ dbcommon::SelectList *sel = convertSelectList(d, context);
+
+ if (result) {
+ retval.resize(result->size() + sel->size());
+ auto end =
+ std::set_intersection(result->begin(), result->end(), sel->begin(),
+ sel->end(), retval.begin());
+ retval.resize(end - retval.begin());
+ result->swap(retval);
+ } else {
+ result = sel;
+ }
+ }
+
+ return dbcommon::CreateDatum(result);
+}
+
+dbcommon::Datum VarExprState::calc(ExprContext *context) {
+ int32_t columnIndex = var->varattno() - 1;
+
+ dbcommon::TupleBatch *batch = nullptr;
+ if (var->varno() == INNER_VAR) {
+ batch = context->innerBatch;
+ } else if (var->varno() == OUTER_VAR) {
+ batch = context->outerBatch;
+ } else {
+ batch = context->scanBatch;
+ }
+
+ if (context->tupleIterValid() && !batch->isScalarTupleBatch()) {
+ batch->getColumn(columnIndex)->readPlainScalar(context->tupleIdx, &scalar);
+ return dbcommon::CreateDatum<dbcommon::Scalar *>(&scalar);
+ }
+
+ dbcommon::Vector *ret;
+
+ if (columnIndex >= 0) {
+ // Case 1. Relation attribute
+ ret = batch->getColumn(columnIndex);
+ } else {
+ // Case 2. System attribute
+ LOG_ERROR(
+ ERRCODE_FEATURE_NOT_SUPPORTED,
+ "System attribute is not supported in univplan::VarExprState::calc");
+ }
+
+ return CreateDatum(ret);
+}
+
+ConstExprState::ConstExprState(const univplan::UnivPlanConst *val)
+ : scalar(dbcommon::Datum()) {
+ retType = univplan::PlanNodeUtil::typeKindMapping(val->type());
+ retTypeMod = val->typemod();
+ if (val->isnull()) {
+ scalar.isnull = true;
+ } else if (univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::TIMESTAMPID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::TIMESTAMPTZID) {
+ scalar.value = dbcommon::CreateDatum(
+ val->value().c_str(), &ts,
+ univplan::PlanNodeUtil::typeKindMapping(val->type()));
+ } else if (univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::DECIMALID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::DECIMALNEWID) {
+ dbcommon::DecimalType t;
+ decimalReg = t.fromString(val->value().c_str());
+ scalar.value = dbcommon::CreateDatum(&decimalReg);
+ } else if (univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::INTERVALID) {
+ intervalReg = dbcommon::IntervalType::fromString(val->value().c_str());
+ scalar.value = dbcommon::CreateDatum(&intervalReg);
+ } else if (univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::BINARYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::IOBASETYPEID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::STRUCTEXID) {
+ auto srcStr = val->value().c_str();
+ auto srcLen = val->value().size();
+ uint32_t dstLen = 0;
+ binary.resize(srcLen + sizeof(dstLen));
+ for (auto i = 0; i < srcLen;) {
+ if (srcStr[i] != '\\') {
+ binary[dstLen++] = srcStr[i];
+ i += 1;
+ } else if (srcStr[i + 1] == '\\') {
+ binary[dstLen++] = '\\';
+ i += 2;
+ } else {
+ binary[dstLen++] = (srcStr[i + 1] - '0') * 64 +
+ (srcStr[i + 2] - '0') * 8 + (srcStr[i + 3] - '0');
+ i += 4;
+ }
+ }
+ scalar.value = dbcommon::CreateDatum<char *>(&binary[0]);
+ scalar.length = dstLen;
+ } else if (univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::SMALLINTARRAYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::INTARRAYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::BIGINTARRAYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::FLOATARRAYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::DOUBLEARRAYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::STRINGARRAYID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::BPCHARARRAYID) {
+ auto typeEnt = reinterpret_cast<dbcommon::ArrayType *>(
+ dbcommon::TypeUtil::instance()
+ ->getTypeEntryById(
+ univplan::PlanNodeUtil::typeKindMapping(val->type()))
+ ->type.get());
+ array = std::move(typeEnt->getScalarFromString(val->value()));
+ scalar.value = dbcommon::CreateDatum(array.get());
+ } else {
+ scalar.value = dbcommon::CreateDatum(
+ val->value().c_str(),
+ univplan::PlanNodeUtil::typeKindMapping(val->type()));
+ }
+
+ if (univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::STRINGID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::VARCHARID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::CHARID ||
+ univplan::PlanNodeUtil::typeKindMapping(val->type()) ==
+ dbcommon::TypeKind::DECIMALNEWID) {
+ scalar.length = val->value().length();
+ }
+}
+
+dbcommon::Datum ConstExprState::calc(ExprContext *context) {
+ return dbcommon::CreateDatum(&scalar);
+}
+
+OpExprState::OpExprState(const univplan::UnivPlanOpExpr *op)
+ : invoker(univplan::PlanNodeUtil::funcKindMapping(op->funcid())) {
+ const dbcommon::FuncEntry *entry =
+ dbcommon::Func::instance()->getFuncEntryById(
+ univplan::PlanNodeUtil::funcKindMapping(op->funcid()));
+ retType = entry->retType;
+}
+
+OpExprState::OpExprState(dbcommon::FuncKind funcId) : invoker(funcId) {
+ const dbcommon::FuncEntry *entry =
+ dbcommon::Func::instance()->getFuncEntryById(
+ univplan::PlanNodeUtil::funcKindMapping(funcId));
+ retType = entry->retType;
+}
+
+dbcommon::Datum OpExprState::calc(ExprContext *context) {
+ invoker.resetPrarmeter();
+ invoker.addParam(dbcommon::CreateDatum(0));
+
+ assert(args.size() == 2 || args.size() == 1);
+ for (ExprState::uptr &arg : args) {
+ invoker.addParam(arg->calc(context));
+ }
+ if (retval) {
+ retval->clear();
+ } else {
+ bool isRetvalVector = true;
+ if (args.size() == 2) {
+ dbcommon::Object *paraL =
+ dbcommon::DatumGetValue<dbcommon::Object *>(invoker.getParam(1));
+ dbcommon::Vector *vecL = dynamic_cast<dbcommon::Vector *>(paraL);
+ dbcommon::Object *paraR =
+ dbcommon::DatumGetValue<dbcommon::Object *>(invoker.getParam(2));
+ dbcommon::Vector *vecR = dynamic_cast<dbcommon::Vector *>(paraR);
+ isRetvalVector = vecL || vecR;
+ } else if (args.size() == 1) {
+ dbcommon::Object *para =
+ dbcommon::DatumGetValue<dbcommon::Object *>(invoker.getParam(1));
+ isRetvalVector = dynamic_cast<dbcommon::Vector *>(para);
+ }
+
+ if (isRetvalVector) {
+ if (retType == dbcommon::TypeKind::BOOLEANID)
+ retval = std::unique_ptr<dbcommon::Object>(new dbcommon::SelectList);
+ else
+ retval = dbcommon::Vector::BuildVector(retType, true, retTypeMod);
+ } else {
+ retval = std::unique_ptr<dbcommon::Object>(new dbcommon::Scalar);
+ }
+ }
+ invoker.setParam(0, dbcommon::CreateDatum<dbcommon::Object *>(retval.get()));
+
+ return invoker.invoke();
+}
+
+dbcommon::Datum FuncExprState::calc(ExprContext *context) {
+ invoker.resetPrarmeter();
+ invoker.addParam(dbcommon::CreateDatum(0));
+
+ for (ExprState::uptr &arg : args) {
+ invoker.addParam(arg->calc(context));
+ }
+
+ if (retval) {
+ retval->clear();
+ } else {
+ bool isVecFunc = false;
+ for (size_t i = 1; i <= args.size(); i++) {
+ dbcommon::Object *para =
+ dbcommon::DatumGetValue<dbcommon::Object *>(invoker.getParam(i));
+ dbcommon::Vector *vec = dynamic_cast<dbcommon::Vector *>(para);
+ if (vec) {
+ isVecFunc = true;
+ break;
+ }
+ }
+ if (func->funcid() == dbcommon::FuncKind::RANDOMF) isVecFunc = true;
+ if (!isVecFunc) {
+ retval = std::unique_ptr<dbcommon::Object>(new dbcommon::Scalar);
+ } else {
+ dbcommon::TypeKind rettype =
+ univplan::PlanNodeUtil::typeKindMapping(func->rettype());
+ if (rettype == dbcommon::TypeKind::BOOLEANID)
+ retval = std::unique_ptr<dbcommon::Object>(new dbcommon::SelectList);
+ else
+ retval = dbcommon::Vector::BuildVector(rettype, true);
+ }
+ }
+ invoker.setParam(0, dbcommon::CreateDatum<dbcommon::Object *>(retval.get()));
+ if (func->funcid() == dbcommon::FuncKind::RANDOMF) {
+ invoker.addParam(dbcommon::CreateDatum(context->outerBatch != nullptr
+ ? context->outerBatch
+ : context->scanBatch));
+ }
+
+ return invoker.invoke();
+}
+
+dbcommon::Datum NullTestState::calc(ExprContext *context) {
+ assert(args.size() == 1);
+
+ auto obj =
+ dbcommon::DatumGetValue<dbcommon::Object *>(args[0]->calc(context));
+
+ if (auto scalar = dynamic_cast<dbcommon::Scalar *>(obj)) {
+ scalarResult_.value = dbcommon::CreateDatum<bool>(scalar->isnull == isNull);
+ return dbcommon::CreateDatum(&scalarResult_);
+ } else {
+ auto vec = reinterpret_cast<dbcommon::Vector *>(obj);
+ size_t size = vec->getNumOfRows();
+ result.resize(0);
+
+ for (size_t i = 0; i < size; ++i) {
+ bool null = vec->isNull(i);
+
+ if (null == isNull) {
+ result.push_back(vec->getPlainIndex(i));
+ }
+ }
+ }
+
+ return dbcommon::CreateDatum(&result);
+}
+
+dbcommon::Datum BooleanTestState::calc(ExprContext *context) {
+ assert(args.size() == 1);
+ for (ExprState::uptr &arg : args) {
+ dbcommon::Vector *vec =
+ dbcommon::DatumGetValue<dbcommon::Vector *>(arg->calc(context));
+
+ size_t size = vec->getNumOfRows();
+ result.reset(new dbcommon::SelectList);
+ result->reserve(size);
+
+ const bool *val = reinterpret_cast<const bool *>(vec->getValue());
+ for (size_t i = 0; i < size; ++i) {
+ uint64_t index = vec->getPlainIndex(i);
+ bool null = vec->isNullPlain(index);
+ if (op->type() == univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_TRUE) {
+ if (!null && val[index]) result->push_back(index);
+ } else if (op->type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_NOT_TRUE) {
+ if (null || !val[index]) result->push_back(index);
+ } else if (op->type() == univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_FALSE) {
+ if (!null && !val[index]) result->push_back(index);
+ } else if (op->type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_NOT_FALSE) {
+ if (null || val[index]) result->push_back(index);
+ } else if (op->type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_UNKNOWN) {
+ if (null) result->push_back(index);
+ } else {
+ assert(op->type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_NOT_UNKNOWN);
+ if (!null) result->push_back(index);
+ }
+ }
+ }
+
+ return dbcommon::CreateDatum(result.get());
+}
+
+dbcommon::Datum BoolExprState::calc(ExprContext *context) {
+ if (op == univplan::BOOLEXPRTYPE::BOOLEXPRTYPE_OR_EXPR) {
+ return calcOr(context);
+ } else if (op == univplan::BOOLEXPRTYPE::BOOLEXPRTYPE_NOT_EXPR) {
+ return calcNot(context);
+ } else {
+ assert(op == univplan::BOOLEXPRTYPE::BOOLEXPRTYPE_AND_EXPR);
+ return calcAnd(context);
+ }
+}
+
+dbcommon::Datum BoolExprState::calcAnd(ExprContext *context) {
+ assert(args.size() >= 2);
+ backupSel_ = context->releaseSelected();
+ dbcommon::SelectList *backupSel = context->getSelectList();
+
+ dbcommon::Object *para0 = args[0]->calc(context);
+ if (dynamic_cast<dbcommon::Scalar *>(para0))
+ LOG_ERROR(ERRCODE_FEATURE_NOT_SUPPORTED, "Feature not supported");
+
+ if (dynamic_cast<dbcommon::SelectList *>(para0)) {
+ if (retval == nullptr)
+ retval =
+ dbcommon::Vector::BuildVector(dbcommon::TypeKind::BOOLEANID, true);
+ reinterpret_cast<dbcommon::SelectList *>(para0)->toVector(
+ reinterpret_cast<dbcommon::Vector *>(retval.get()));
+ } else {
+ retval =
+ reinterpret_cast<dbcommon::Vector *>(para0)->cloneSelected(nullptr);
+ }
+
+ dbcommon::Vector *retVector =
+ reinterpret_cast<dbcommon::Vector *>(retval.get());
+
+ std::unique_ptr<dbcommon::Vector> tmpVectorBackup;
+
+ for (auto i = 1; i < args.size(); i++) {
+ auto &it = args[i];
+ dbcommon::Object *para = it->calc(context);
+
+ auto lhsVector = retVector->cloneSelected(nullptr);
+ dbcommon::Vector *rhsVector = reinterpret_cast<dbcommon::Vector *>(para);
+
+ if (dynamic_cast<dbcommon::Scalar *>(para))
+ LOG_ERROR(ERRCODE_FEATURE_NOT_SUPPORTED, "Feature not supported");
+
+ if (auto sel = dynamic_cast<dbcommon::SelectList *>(para)) {
+ if (tmpVectorBackup == nullptr)
+ tmpVectorBackup =
+ dbcommon::Vector::BuildVector(dbcommon::TypeKind::BOOLEANID, true);
+ rhsVector = tmpVectorBackup.get();
+ sel->toVector(rhsVector);
+ }
+
+ dbcommon::FixedSizeTypeVectorRawData<bool> lhs(lhsVector.get());
+ dbcommon::FixedSizeTypeVectorRawData<bool> rhs(rhsVector);
+ retVector->resize(context->getNumOfRowsPlain(), nullptr, lhs.nulls,
+ rhs.nulls);
+ dbcommon::FixedSizeTypeVectorRawData<bool> ret(retVector);
+ auto setBoolean = [&](uint64_t plainIdx) {
+ ret.values[plainIdx] = lhs.values[plainIdx] & rhs.values[plainIdx];
+ };
+ dbcommon::transformVector(ret.plainSize, nullptr, nullptr, setBoolean);
+
+ if (ret.nulls) {
+ auto setNullFromLhs = [&](uint64_t plainIdx) {
+ if (lhs.values[plainIdx] == false)
+ const_cast<bool *>(ret.nulls)[plainIdx] = false;
+ };
+ dbcommon::transformVector(ret.plainSize, nullptr, lhs.nulls,
+ setNullFromLhs);
+
+ auto setNullFromRhs = [&](uint64_t plainIdx) {
+ if (rhs.values[plainIdx] == false)
+ const_cast<bool *>(ret.nulls)[plainIdx] = false;
+ };
+ dbcommon::transformVector(ret.plainSize, nullptr, rhs.nulls,
+ setNullFromRhs);
+ }
+ }
+
+ context->setSelected(backupSel);
+ auto retsel = convertSelectList(dbcommon::CreateDatum(retVector), context);
+ return dbcommon::CreateDatum(retsel);
+}
+
+dbcommon::Datum BoolExprState::calcOr(ExprContext *context) {
+ assert(args.size() >= 2);
+ backupSel_ = context->releaseSelected();
+ dbcommon::SelectList *backupSel = context->getSelectList();
+ if (retval == nullptr) retval.reset(new dbcommon::SelectList);
+ retval->clear();
+ dbcommon::SelectList *retsel =
+ static_cast<dbcommon::SelectList *>(retval.get());
+ retsel->setPlainSize(0);
+
+ dbcommon::Datum d = args[0]->calc(context);
+ dbcommon::SelectList *sel = convertSelectList(d, context);
+ *retsel = *sel;
+
+ for (auto i = 1; i < args.size(); i++) {
+ auto &it = args[i];
+ dbcommon::Datum d = it->calc(context);
+ dbcommon::SelectList *sel = convertSelectList(d, context);
+
+ dbcommon::SelectList tmp = *retsel;
+
+ retsel->resize(tmp.size() + sel->size());
+ auto end = std::set_union(tmp.begin(), tmp.end(), sel->begin(), sel->end(),
+ retsel->begin());
+ retsel->resize(end - retsel->begin());
+ retsel->setNulls(context->getNumOfRowsPlain(), nullptr, tmp.getNulls(),
+ sel->getNulls());
+ }
+ retsel->setNulls(context->getNumOfRowsPlain(), retsel, false);
+
+ context->setSelected(backupSel);
+ return dbcommon::CreateDatum(retval.get());
+}
+
+dbcommon::Datum BoolExprState::calcNot(ExprContext *context) {
+ assert(args.size() == 1);
+ backupSel_ = context->releaseSelected();
+ dbcommon::SelectList *backupSel = context->getSelectList();
+ dbcommon::Datum d = args.front()->calc(context);
+
+ if (auto sel = dynamic_cast<dbcommon::SelectList *>(
+ dbcommon::DatumGetValue<dbcommon::Object *>(d))) {
+ if (retval == nullptr) retval.reset(new dbcommon::SelectList);
+ auto retsel = reinterpret_cast<dbcommon::SelectList *>(retval.get());
+ *retsel = sel->getComplement(context->getNumOfRowsPlain());
+ retsel->setNulls(context->getNumOfRowsPlain(), nullptr, sel->getNulls());
+
+ if (backupSel) {
+ auto end = std::set_intersection(retsel->begin(), retsel->end(),
+ backupSel->begin(), backupSel->end(),
+ retsel->begin());
+ retsel->resize(end - retsel->begin());
+ }
+ } else if (dbcommon::BooleanVector *vec =
+ dynamic_cast<dbcommon::BooleanVector *>(
+ dbcommon::DatumGetValue<dbcommon::Object *>(d))) {
+ if (retval == nullptr) retval.reset(new dbcommon::SelectList);
+ auto retsel = reinterpret_cast<dbcommon::SelectList *>(retval.get());
+ dbcommon::SelectList tmp;
+ tmp.fromVector(vec);
+ *retsel = tmp.getComplement(context->getNumOfRowsPlain());
+ retsel->setNulls(context->getNumOfRowsPlain(), nullptr, tmp.getNulls());
+
+ if (backupSel) {
+ auto end = std::set_intersection(retsel->begin(), retsel->end(),
+ backupSel->begin(), backupSel->end(),
+ retsel->begin());
+ retsel->resize(end - retsel->begin());
+ }
+ } else {
+ dbcommon::Scalar *scalar = static_cast<dbcommon::Scalar *>(
+ dbcommon::DatumGetValue<dbcommon::Object *>(d));
+ if (scalar->value.value.i8)
+ scalar->value.value.i8 = 0;
+ else
+ scalar->value.value.i8 = 1;
+ retval.reset(new dbcommon::Scalar(*scalar));
+ }
+
+ context->setSelected(backupSel);
+ return dbcommon::CreateDatum(retval.get());
+}
+
+ExprState::uptr InitExpr(const univplan::UnivPlanExprPolyList *exprs) {
+ return ExprState::uptr(new ListExprState(exprs));
+}
+
+ExprState::uptr InitExpr(const univplan::UnivPlanExprPoly *expr) {
+ switch (expr->type()) {
+ case univplan::UNIVPLAN_EXPR_VAR:
+ return ExprState::uptr(new VarExprState(&expr->var()));
+ case univplan::UNIVPLAN_EXPR_CONST:
+ return ExprState::uptr(new ConstExprState(&expr->val()));
+ case univplan::UNIVPLAN_EXPR_TARGETENTRY:
+ return InitExpr(&expr->targetentry().expression());
+ case univplan::UNIVPLAN_EXPR_OPEXPR: {
+ const univplan::UnivPlanOpExpr &op = expr->opexpr();
+ bool predictable =
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(op.funcid()))
+ ->predictable;
+ if (!predictable)
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "FuncExpr %d is not predictable",
+ op.funcid());
+ OpExprState::uptr retval(new OpExprState(&op));
+ for (int i = 0; i < op.args_size(); ++i)
+ retval->addArg(InitExpr(&op.args(i)));
+ return std::move(retval);
+ }
+ case univplan::UNIVPLAN_EXPR_FUNCEXPR: {
+ const univplan::UnivPlanFuncExpr &func = expr->funcexpr();
+ bool predictable =
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(func.funcid()))
+ ->predictable;
+ if (!predictable)
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "FuncExpr %d is not predictable",
+ func.funcid());
+ FuncExprState::uptr retval(new FuncExprState(&func));
+ for (int i = 0; i < func.args_size(); ++i)
+ retval->addArg(InitExpr(&func.args(i)));
+ return std::move(retval);
+ }
+ case univplan::UNIVPLAN_EXPR_NULLTEST: {
+ const univplan::UnivPlanNullTest &op = expr->nulltest();
+ NullTestState::uptr retval(new NullTestState(&op));
+ retval->addArg(InitExpr(&op.arg()));
+ return std::move(retval);
+ }
+ case univplan::UNIVPLAN_EXPR_BOOLEANTEST: {
+ const univplan::UnivPlanBooleanTest &op = expr->booltest();
+ BooleanTestState::uptr retval(new BooleanTestState(&op));
+ retval->addArg(InitExpr(&op.arg()));
+ return std::move(retval);
+ }
+ case univplan::UNIVPLAN_EXPR_BOOLEXPR: {
+ const univplan::UnivPlanBoolExpr &op = expr->boolexpr();
+ BoolExprState::uptr retval(new BoolExprState(&op));
+ for (int i = 0; i < op.args_size(); ++i)
+ retval->addArg(InitExpr(&op.args(i)));
+ return std::move(retval);
+ }
+ default:
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "expr type %d is not predictable",
+ expr->type());
+ }
+ return nullptr;
+}
+
+bool do_opexpr2(int col, const univplan::UnivPlanOpExpr &op,
+ std::vector<std::unique_ptr<IndexExpr> > &allExpr, // NOLINT
+ std::vector<std::unique_ptr<IndexExpr> > &equalExpr, // NOLINT
+ int *equal) {
+ std::unique_ptr<IndexExpr> idx(new IndexExpr());
+ const univplan::UnivPlanVar &var = op.args(0).var();
+ int att = var.varattno();
+ int typeId = var.typeid_();
+ if (typeId == dbcommon::TypeKind::DECIMALID ||
+ typeId == dbcommon::TypeKind::BOOLEANID) {
+ return false;
+ }
+ int modify = var.typemod();
+ std::string funcName =
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(op.funcid()))
+ ->funcName;
+ if (att - 1 == col &&
+ (!(dbcommon::StringUtil::countReplicates(funcName, "not_equal") == 1))) {
+ const univplan::UnivPlanConst &con = op.args(1).val();
+ idx->colidx = att;
+ idx->typeId = typeId;
+ idx->oper = funcName;
+ idx->constVal = con.value();
+ idx->typeModify = modify;
+ if (!(dbcommon::StringUtil::countReplicates(funcName, "equal") == 1)) {
+ allExpr.push_back(std::move(idx));
+ *equal = 0;
+ } else {
+ equalExpr.push_back(std::move(idx));
+ *equal = 1;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool do_boolexpr2(
+ int pk, const univplan::UnivPlanBoolExpr &expr,
+ std::vector<std::unique_ptr<IndexExpr> > &allExpr, // NOLINT
+ std::vector<std::unique_ptr<IndexExpr> > &equalExpr, // NOLINT
+ int *equal) {
+ int args_size = expr.args_size();
+ bool hasExpr = false;
+ for (int i = 0; i < args_size; ++i) {
+ const univplan::UnivPlanExprPoly &op = expr.args(i);
+ switch (op.type()) {
+ case univplan::UNIVPLAN_EXPR_OPEXPR: {
+ const univplan::UnivPlanOpExpr &opex = op.opexpr();
+ bool has = do_opexpr2(pk, opex, allExpr, equalExpr, equal);
+ if (*equal == 1) return true;
+ if (has) hasExpr = true;
+ break;
+ }
+ case univplan::UNIVPLAN_EXPR_BOOLEXPR: {
+ const univplan::UnivPlanBoolExpr &opex = op.boolexpr();
+ bool has = do_boolexpr2(pk, opex, allExpr, equalExpr, equal);
+ if (*equal == 1) return true;
+ if (has) hasExpr = true;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return hasExpr;
+}
+
+bool loopContinue(
+ int pkCol, const univplan::UnivPlanExprPolyList *filterExprs,
+ std::vector<std::unique_ptr<IndexExpr> > &allExpr, // NOLINT
+ std::vector<std::unique_ptr<IndexExpr> > &equalExpr) { // NOLINT
+ int filterSize = filterExprs->size();
+ assert(filterSize > 0);
+ bool hasExpr = false;
+ for (int i = 0; i < filterSize; ++i) {
+ const univplan::UnivPlanExprPoly &ep = filterExprs->Get(i);
+ switch (ep.type()) {
+ case univplan::UNIVPLAN_EXPR_OPEXPR: {
+ const univplan::UnivPlanOpExpr &op = ep.opexpr();
+ int equal = 0;
+ bool has = do_opexpr2(pkCol, op, allExpr, equalExpr, &equal);
+ if (equal == 1) return true;
+ if (has) hasExpr = true;
+ break;
+ }
+ case univplan::UNIVPLAN_EXPR_BOOLEXPR: {
+ const univplan::UnivPlanBoolExpr &op = ep.boolexpr();
+ if (op.type() == univplan::BOOLEXPRTYPE::BOOLEXPRTYPE_AND_EXPR) {
+ int equal = 0;
+ bool has = do_boolexpr2(pkCol, op, allExpr, equalExpr, &equal);
+ if (equal == 1) return true;
+ if (has) hasExpr = true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return hasExpr;
+}
+
+std::vector<std::vector<std::unique_ptr<IndexExpr> > > getIndexExpr2(
+ const std::vector<int> &index,
+ const univplan::UnivPlanExprPolyList *filterExprs) {
+ std::vector<std::vector<std::unique_ptr<IndexExpr> > > indexExprVec;
+ int indexSize = index.size();
+ assert(indexSize > 0);
+ for (int i = 0; i < indexSize; ++i) {
+ int col = index[i];
+ std::vector<std::unique_ptr<IndexExpr> > allExpr;
+ std::vector<std::unique_ptr<IndexExpr> > equalExpr;
+ bool loop = loopContinue(col, filterExprs, allExpr, equalExpr);
+ if (!loop) return indexExprVec;
+ int equalSize = equalExpr.size();
+ int allSize = allExpr.size();
+ if (equalSize > 0) {
+ indexExprVec.push_back(std::move(equalExpr));
+ continue;
+ } else {
+ if (allSize > 0) {
+ indexExprVec.push_back(std::move(allExpr));
+ return indexExprVec;
+ }
+ }
+ }
+ return indexExprVec;
+}
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/common/expression.h b/depends/univplan/src/univplan/common/expression.h
new file mode 100644
index 0000000..1f87c3a
--- /dev/null
+++ b/depends/univplan/src/univplan/common/expression.h
@@ -0,0 +1,350 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_EXPRESSION_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_EXPRESSION_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "dbcommon/function/invoker.h"
+#include "dbcommon/type/decimal.h"
+#include "dbcommon/type/interval.h"
+#include "dbcommon/utils/string-util.h"
+
+#include "univplan/common/plannode-util.h"
+
+namespace dbcommon {
+class TupleBatch;
+}
+
+namespace univplan {
+
+class ExprContext {
+ public:
+ ExprContext()
+ : innerBatch(nullptr), outerBatch(nullptr), scanBatch(nullptr) {}
+ ExprContext(dbcommon::TupleBatch *outerBatch,
+ dbcommon::TupleBatch *innerBatch, dbcommon::TupleBatch *scanBatch)
+ : outerBatch(outerBatch), innerBatch(innerBatch), scanBatch(scanBatch) {
+ assert((scanBatch && !innerBatch && !outerBatch) ||
+ (outerBatch && !innerBatch && !scanBatch) ||
+ (innerBatch && outerBatch && !scanBatch));
+ }
+
+ dbcommon::TupleBatch *innerBatch;
+ dbcommon::TupleBatch *outerBatch;
+ dbcommon::TupleBatch *scanBatch;
+
+ // Iterator of plain index for processing input tuple by tuple rather than TB
+ // by TB
+ uint64_t tupleIdx = -1;
+ bool tupleIterValid() { return tupleIdx != -1; }
+ void setTupleIter(uint64_t tupleIdx) { this->tupleIdx = tupleIdx; }
+ void disableTupleIter() { tupleIdx = -1; }
+
+ public:
+ void setSelected(dbcommon::SelectList *selected) {
+ if (innerBatch) innerBatch->setSelected(selected);
+ if (outerBatch) outerBatch->setSelected(selected);
+ if (scanBatch) scanBatch->setSelected(selected);
+ }
+
+ std::unique_ptr<dbcommon::SelectList> releaseSelected() {
+ if (innerBatch) return innerBatch->releaseSelected();
+ if (outerBatch) return outerBatch->releaseSelected();
+ if (scanBatch) return scanBatch->releaseSelected();
+ return nullptr;
+ }
+
+ size_t getNumOfRows() {
+ if (innerBatch) return innerBatch->getNumOfRows();
+ if (outerBatch) return outerBatch->getNumOfRows();
+ if (scanBatch) return scanBatch->getNumOfRows();
+
+ // tupleCount=1 special for constant select
+ return 1;
+ }
+
+ size_t getNumOfRowsPlain() {
+ if (innerBatch) return innerBatch->getNumOfRowsPlain();
+ if (outerBatch) return outerBatch->getNumOfRowsPlain();
+ if (scanBatch) return scanBatch->getNumOfRowsPlain();
+
+ // tupleCount=1 special for constant select
+ return 1;
+ }
+
+ dbcommon::SelectList *getSelectList() {
+ if (innerBatch && innerBatch->getSelected())
+ return innerBatch->getSelected();
+ if (outerBatch && outerBatch->getSelected())
+ return outerBatch->getSelected();
+ if (scanBatch && scanBatch->getSelected()) return scanBatch->getSelected();
+ return nullptr;
+ }
+};
+
+class ExprState {
+ public:
+ ExprState() {}
+ virtual ~ExprState() {}
+
+ typedef std::unique_ptr<ExprState> uptr;
+
+ virtual dbcommon::Datum calc(ExprContext *context) = 0;
+
+ dbcommon::SelectList *convertSelectList(const dbcommon::Datum &d,
+ ExprContext *context);
+
+ dbcommon::TypeKind getRetType() { return retType; }
+
+ int64_t getRetTypeModifier() { return retTypeMod; }
+
+ void addArg(ExprState::uptr arg) { args.push_back(std::move(arg)); }
+
+ ExprState *getArg(size_t idx) { return args[idx].get(); }
+
+ protected:
+ dbcommon::TypeKind retType = dbcommon::TypeKind::UNKNOWNID;
+ int64_t retTypeMod = -1;
+ std::vector<ExprState::uptr> args;
+
+ // When relying on current ExprContext's SelectList content, ExprState should
+ // backup the SelectList.
+ std::unique_ptr<dbcommon::SelectList> backupSel_;
+
+ private:
+ std::unique_ptr<dbcommon::SelectList> convertedSelectlist;
+};
+
+class ListExprState : public ExprState {
+ public:
+ explicit ListExprState(const univplan::UnivPlanExprPolyList *exprs);
+ ~ListExprState() {}
+
+ typedef std::unique_ptr<ListExprState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ private:
+ dbcommon::SelectList retval;
+};
+
+class VarExprState : public ExprState {
+ public:
+ explicit VarExprState(const univplan::UnivPlanVar *var) : var(var) {
+ retType = univplan::PlanNodeUtil::typeKindMapping(var->typeid_());
+ retTypeMod = var->typemod();
+ }
+ ~VarExprState() {}
+
+ typedef std::unique_ptr<VarExprState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ int32_t getAttributeNumber() const { return var->varattno(); }
+
+ uint32_t getVarNo() const { return var->varno(); }
+
+ private:
+ const univplan::UnivPlanVar *var;
+ // iterator for processing input tuple by tuple
+ dbcommon::Scalar scalar;
+};
+
+class ConstExprState : public ExprState {
+ public:
+ explicit ConstExprState(const univplan::UnivPlanConst *val);
+ ~ConstExprState() {}
+
+ typedef std::unique_ptr<ConstExprState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ private:
+ dbcommon::Scalar scalar;
+ dbcommon::Timestamp ts;
+ dbcommon::DecimalVar decimalReg;
+ dbcommon::IntervalVar intervalReg;
+ std::vector<char> binary;
+ dbcommon::Vector::uptr array;
+};
+
+class OpExprState : public ExprState {
+ public:
+ explicit OpExprState(const univplan::UnivPlanOpExpr *op);
+ explicit OpExprState(dbcommon::FuncKind funcId);
+ ~OpExprState() {}
+
+ typedef std::unique_ptr<OpExprState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ private:
+ dbcommon::Invoker invoker;
+ std::unique_ptr<dbcommon::Object> retval;
+};
+
+class FuncExprState : public ExprState {
+ public:
+ explicit FuncExprState(const univplan::UnivPlanFuncExpr *func)
+ : func(func),
+ invoker(univplan::PlanNodeUtil::funcKindMapping(func->funcid())) {}
+ ~FuncExprState() {}
+
+ typedef std::unique_ptr<FuncExprState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ private:
+ const univplan::UnivPlanFuncExpr *func;
+ dbcommon::Invoker invoker;
+ std::unique_ptr<dbcommon::Object> retval;
+};
+
+class NullTestState : public ExprState {
+ public:
+ explicit NullTestState(const univplan::UnivPlanNullTest *op)
+ : op(op),
+ isNull(op->type() == univplan::NULLTESTTYPE::NULLTESTTYPE_IS_NULL) {}
+
+ explicit NullTestState(bool isNull) : op(nullptr), isNull(isNull) {}
+
+ ~NullTestState() {}
+
+ typedef std::unique_ptr<NullTestState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ private:
+ const univplan::UnivPlanNullTest *op;
+ bool isNull;
+ dbcommon::SelectList result;
+ dbcommon::Scalar scalarResult_;
+};
+
+class BooleanTestState : public ExprState {
+ public:
+ explicit BooleanTestState(const univplan::UnivPlanBooleanTest *op) : op(op) {}
+ ~BooleanTestState() {}
+
+ typedef std::unique_ptr<BooleanTestState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+
+ private:
+ const univplan::UnivPlanBooleanTest *op;
+ std::unique_ptr<dbcommon::SelectList> result;
+};
+
+class BoolExprState : public ExprState {
+ public:
+ explicit BoolExprState(const univplan::UnivPlanBoolExpr *expr)
+ : op(expr->type()) {}
+ ~BoolExprState() {}
+
+ typedef std::unique_ptr<BoolExprState> uptr;
+
+ dbcommon::Datum calc(ExprContext *context) override;
+ dbcommon::Datum calcAnd(ExprContext *context);
+ dbcommon::Datum calcOr(ExprContext *context);
+ dbcommon::Datum calcNot(ExprContext *context);
+
+ private:
+ const univplan::BOOLEXPRTYPE op;
+ std::unique_ptr<dbcommon::Object> retval;
+};
+
+ExprState::uptr InitExpr(const univplan::UnivPlanExprPoly *expr);
+ExprState::uptr InitExpr(const univplan::UnivPlanExprPolyList *exprs);
+
+/* those interface only for magma index */
+struct IndexExpr {
+ IndexExpr() : colidx(-1), typeId(-1), typeModify(-1) {}
+
+ IndexExpr(const IndexExpr &idx) {
+ colidx = idx.colidx;
+ typeId = idx.typeId;
+ oper = idx.oper;
+ constVal = idx.constVal;
+ typeModify = idx.typeModify;
+ }
+
+ IndexExpr &operator=(const IndexExpr &idx) {
+ colidx = idx.colidx;
+ typeId = idx.typeId;
+ oper = idx.oper;
+ constVal = idx.constVal;
+ typeModify = idx.typeModify;
+ return *this;
+ }
+
+ bool isEqual() {
+ return dbcommon::StringUtil::countReplicates(oper, "equal");
+ }
+
+ bool isGreater() {
+ return dbcommon::StringUtil::countReplicates(oper, "greater");
+ }
+
+ bool isLessthan() {
+ return dbcommon::StringUtil::countReplicates(oper, "less");
+ }
+
+ ~IndexExpr() {}
+ int colidx;
+ int typeId;
+ int typeModify;
+ std::string oper;
+ std::string constVal;
+};
+
+bool do_opexpr(const univplan::UnivPlanOpExpr &op, IndexExpr *index, int pk,
+ int *equal);
+
+bool do_boolexpr(const univplan::UnivPlanBoolExpr &expr, IndexExpr *index,
+ int pk, int *equal);
+
+std::vector<std::unique_ptr<IndexExpr> > getIndexExpr(
+ const std::vector<int> &index,
+ const univplan::UnivPlanExprPolyList *filterExprs);
+
+bool do_opexpr2(int pk, const univplan::UnivPlanOpExpr &op,
+ std::vector<std::unique_ptr<IndexExpr> > &allExpr, // NOLINT
+ std::vector<std::unique_ptr<IndexExpr> > &equalExpr, // NOLINT
+ int *equal);
+bool do_boolexpr2(
+ int pk, const univplan::UnivPlanBoolExpr &expr,
+ std::vector<std::unique_ptr<IndexExpr> > &allExpr, // NOLINT
+ std::vector<std::unique_ptr<IndexExpr> > &equalExpr, // NOLINT
+ int *equal);
+bool loopContinue(
+ int pkCol, const univplan::UnivPlanExprPolyList *filterExprs,
+ std::vector<std::unique_ptr<IndexExpr> > &allExpr, // NOLINT
+ std::vector<std::unique_ptr<IndexExpr> > &equalExpr); // NOLINT
+
+std::vector<std::vector<std::unique_ptr<IndexExpr> > > getIndexExpr2(
+ const std::vector<int> &index,
+ const univplan::UnivPlanExprPolyList *filterExprs);
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_EXPRESSION_H_
diff --git a/depends/univplan/src/univplan/common/plannode-util.h b/depends/univplan/src/univplan/common/plannode-util.h
new file mode 100644
index 0000000..33079bb
--- /dev/null
+++ b/depends/univplan/src/univplan/common/plannode-util.h
@@ -0,0 +1,336 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_UTIL_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_UTIL_H_
+
+#include <algorithm>
+#include <utility>
+
+#include "dbcommon/log/logger.h"
+#include "dbcommon/type/type-kind.h"
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-agg.h"
+#include "univplan/univplanbuilder/univplanbuilder-append.h"
+#include "univplan/univplanbuilder/univplanbuilder-connector.h"
+#include "univplan/univplanbuilder/univplanbuilder-ext-gs-scan.h"
+#include "univplan/univplanbuilder/univplanbuilder-hash.h"
+#include "univplan/univplanbuilder/univplanbuilder-hashjoin.h"
+#include "univplan/univplanbuilder/univplanbuilder-insert.h"
+#include "univplan/univplanbuilder/univplanbuilder-limit.h"
+#include "univplan/univplanbuilder/univplanbuilder-material.h"
+#include "univplan/univplanbuilder/univplanbuilder-mergejoin.h"
+#include "univplan/univplanbuilder/univplanbuilder-nestloop.h"
+#include "univplan/univplanbuilder/univplanbuilder-result.h"
+#include "univplan/univplanbuilder/univplanbuilder-scan-seq.h"
+#include "univplan/univplanbuilder/univplanbuilder-shareinput-scan.h"
+#include "univplan/univplanbuilder/univplanbuilder-sink.h"
+#include "univplan/univplanbuilder/univplanbuilder-sort.h"
+#include "univplan/univplanbuilder/univplanbuilder-subquery-scan.h"
+#include "univplan/univplanbuilder/univplanbuilder-unique.h"
+
+namespace dbcommon {
+enum FuncKind : uint32_t;
+};
+
+namespace univplan {
+
+class PlanNodeUtil {
+ public:
+ PlanNodeUtil() {}
+ ~PlanNodeUtil() {}
+
+ static UnivPlanBuilderNode::uptr createPlanBuilderNode(
+ UNIVPLANNODETYPE ntype) {
+ UnivPlanBuilderNode::uptr res;
+ switch (ntype) {
+ case UNIVPLAN_AGG:
+ res.reset(new UnivPlanBuilderAgg());
+ break;
+ case UNIVPLAN_SCAN_SEQ:
+ res.reset(new UnivPlanBuilderScanSeq());
+ break;
+ case UNIVPLAN_CONNECTOR:
+ res.reset(new UnivPlanBuilderConnector());
+ break;
+ case UNIVPLAN_SORT:
+ res.reset(new UnivPlanBuilderSort());
+ break;
+ case UNIVPLAN_EXT_GS_SCAN:
+ res.reset(new UnivPlanBuilderExtGSScan());
+ break;
+ case UNIVPLAN_LIMIT:
+ res.reset(new UnivPlanBuilderLimit());
+ break;
+ case UNIVPLAN_APPEND:
+ res.reset(new UnivPlanBuilderAppend());
+ break;
+ case UNIVPLAN_NESTLOOP:
+ res.reset(new UnivPlanBuilderNestLoop());
+ break;
+ case UNIVPLAN_HASHJOIN:
+ res.reset(new UnivPlanBuilderHashJoin());
+ break;
+ case UNIVPLAN_MERGEJOIN:
+ res.reset(new UnivPlanBuilderMergeJoin());
+ break;
+ case UNIVPLAN_MATERIAL:
+ res.reset(new UnivPlanBuilderMaterial());
+ break;
+ case UNIVPLAN_RESULT:
+ res.reset(new UnivPlanBuilderResult());
+ break;
+ case UNIVPLAN_HASH:
+ res.reset(new UnivPlanBuilderHash());
+ break;
+ case UNIVPLAN_SUBQUERYSCAN:
+ res.reset(new UnivPlanBuilderSubqueryScan());
+ break;
+ case UNIVPLAN_UNIQUE:
+ res.reset(new UnivPlanBuilderUnique());
+ break;
+ case UNIVPLAN_INSERT:
+ res.reset(new UnivPlanBuilderInsert());
+ break;
+ case UNIVPLAN_SHAREINPUTSCAN:
+ res.reset(new UnivPlanBuilderShareInputScan());
+ break;
+ default:
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "PlanNodeUtil::createPlanBuilderNode can't handle "
+ "UNIVPLANNODETYPE %d",
+ ntype);
+ }
+ return std::move(res);
+ }
+
+ static const UnivPlanPlanNode &getPlanNode(const UnivPlanPlanNodePoly &node) {
+ if (node.has_connector()) {
+ return node.connector().super();
+ } else if (node.has_scanseq()) {
+ return node.scanseq().super();
+ } else if (node.has_converge()) {
+ return node.converge().super();
+ } else if (node.has_shuffle()) {
+ return node.shuffle().super();
+ } else if (node.has_broadcast()) {
+ return node.broadcast().super();
+ } else if (node.has_sink()) {
+ return node.sink().super();
+ } else if (node.has_agg()) {
+ return node.agg().super();
+ } else if (node.has_sort()) {
+ return node.sort().super();
+ } else if (node.has_extgsscan()) {
+ return node.extgsscan().super();
+ } else if (node.has_extgsfilter()) {
+ return node.extgsfilter().super();
+ } else if (node.has_extgsproject()) {
+ return node.extgsproject().super();
+ } else if (node.has_limit()) {
+ return node.limit().super();
+ } else if (node.has_append()) {
+ return node.append().super();
+ } else if (node.has_nestloop()) {
+ return node.nestloop().super();
+ } else if (node.has_hashjoin()) {
+ return node.hashjoin().super();
+ } else if (node.has_mergejoin()) {
+ return node.mergejoin().super();
+ } else if (node.has_material()) {
+ return node.material().super();
+ } else if (node.has_result()) {
+ return node.result().super();
+ } else if (node.has_hash()) {
+ return node.hash().super();
+ } else if (node.has_subqueryscan()) {
+ return node.subqueryscan().super();
+ } else if (node.has_unique()) {
+ return node.unique().super();
+ } else if (node.has_insert()) {
+ return node.insert().super();
+ } else if (node.has_shareinputscan()) {
+ return node.shareinputscan().super();
+ } else {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "PlanNodeUtil::getPlanNode type %d not supported", node.type());
+ }
+ }
+
+ static UnivPlanPlanNode *getMutablePlanNode(UnivPlanPlanNodePoly *node) {
+ if (node->has_connector()) {
+ return node->mutable_connector()->mutable_super();
+ } else if (node->has_scanseq()) {
+ return node->mutable_scanseq()->mutable_super();
+ } else if (node->has_converge()) {
+ return node->mutable_converge()->mutable_super();
+ } else if (node->has_shuffle()) {
+ return node->mutable_shuffle()->mutable_super();
+ } else if (node->has_broadcast()) {
+ return node->mutable_broadcast()->mutable_super();
+ } else if (node->has_sink()) {
+ return node->mutable_sink()->mutable_super();
+ } else if (node->has_agg()) {
+ return node->mutable_agg()->mutable_super();
+ } else if (node->has_sort()) {
+ return node->mutable_sort()->mutable_super();
+ } else if (node->has_limit()) {
+ return node->mutable_limit()->mutable_super();
+ } else if (node->has_append()) {
+ return node->mutable_append()->mutable_super();
+ } else if (node->has_nestloop()) {
+ return node->mutable_nestloop()->mutable_super();
+ } else if (node->has_hashjoin()) {
+ return node->mutable_hashjoin()->mutable_super();
+ } else if (node->has_mergejoin()) {
+ return node->mutable_mergejoin()->mutable_super();
+ } else if (node->has_material()) {
+ return node->mutable_material()->mutable_super();
+ } else if (node->has_result()) {
+ return node->mutable_result()->mutable_super();
+ } else if (node->has_hash()) {
+ return node->mutable_hash()->mutable_super();
+ } else if (node->has_subqueryscan()) {
+ return node->mutable_subqueryscan()->mutable_super();
+ } else if (node->has_extgsscan()) {
+ return node->mutable_extgsscan()->mutable_super();
+ } else if (node->has_extgsfilter()) {
+ return node->mutable_extgsfilter()->mutable_super();
+ } else if (node->has_extgsproject()) {
+ return node->mutable_extgsproject()->mutable_super();
+ } else if (node->has_unique()) {
+ return node->mutable_unique()->mutable_super();
+ } else if (node->has_insert()) {
+ return node->mutable_insert()->mutable_super();
+ } else if (node->has_shareinputscan()) {
+ return node->mutable_shareinputscan()->mutable_super();
+ } else {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "PlanNodeUtil::getPlanNode type %d not supported",
+ node->type());
+ }
+ }
+
+ static const UnivPlanPlan *getPlan(const UnivPlanPlan &cur, int32_t stageNo) {
+ if (cur.stageno() == stageNo) return &cur;
+ for (int i = 0; i < cur.childstages_size(); i++) {
+ const UnivPlanPlan *ret = getPlan(cur.childstages(i), stageNo);
+ if (ret != nullptr) return ret;
+ }
+ return nullptr;
+ }
+
+ static dbcommon::TypeKind exprType(const UnivPlanExprPoly &expr) {
+ if (expr.has_opexpr()) {
+ return typeKindMapping(expr.opexpr().rettype());
+ } else if (expr.has_val()) {
+ return typeKindMapping(expr.val().type());
+ } else if (expr.has_targetentry()) {
+ return exprType(expr.targetentry().expression());
+ } else if (expr.has_aggref()) {
+ return typeKindMapping(expr.aggref().rettype());
+ } else if (expr.has_var()) {
+ return typeKindMapping(expr.var().typeid_());
+ } else if (expr.has_funcexpr()) {
+ return typeKindMapping(expr.funcexpr().rettype());
+ } else if (expr.has_nulltest() || expr.has_boolexpr() ||
+ expr.has_booltest()) {
+ return dbcommon::TypeKind::BOOLEANID;
+ } else if (expr.has_caseexpr()) {
+ return typeKindMapping(expr.caseexpr().casetype());
+ } else if (expr.has_param()) {
+ return typeKindMapping(expr.param().typeid_());
+ } else if (expr.has_subplan()) {
+ if (expr.subplan().sublinktype() == univplan::SUBLINKTYPE::EXPR_SUBLINK)
+ return typeKindMapping(expr.subplan().typeid_());
+ else
+ return dbcommon::TypeKind::BOOLEANID;
+ } else if (expr.has_coalesceexpr()) {
+ return typeKindMapping(expr.coalesceexpr().coalescetype());
+ } else if (expr.has_nullifexpr()) {
+ return typeKindMapping(expr.nullifexpr().rettype());
+ } else if (expr.has_distinctexpr()) {
+ return typeKindMapping(expr.distinctexpr().rettype());
+ } else {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "PlanNodeUtil::exprType expr %d not supported", expr.type());
+ }
+ }
+
+ static int64_t exprTypeMod(const UnivPlanExprPoly &expr) {
+ if (expr.has_val()) {
+ return (expr.val().typemod());
+ } else if (expr.has_var()) {
+ return (expr.var().typemod());
+ } else if (expr.has_targetentry()) {
+ return exprType(expr.targetentry().expression());
+ } else if (expr.has_param()) {
+ return (expr.param().typemod());
+ } else if (expr.has_subplan()) {
+ return (expr.subplan().typemod());
+ } else if (expr.has_coalesceexpr()) {
+ return expr.coalesceexpr().coalescetypemod();
+ } else if (expr.has_nullifexpr()) {
+ return expr.nullifexpr().typemod();
+ }
+
+ int64_t ret = -1;
+ if (expr.has_opexpr()) {
+ for (auto arg : expr.opexpr().args())
+ ret = std::max(exprTypeMod(arg), ret);
+ return ret;
+ } else if (expr.has_aggref()) {
+ for (auto arg : expr.aggref().args())
+ ret = std::max(exprTypeMod(arg), ret);
+ return ret;
+ } else if (expr.has_funcexpr()) {
+ for (auto arg : expr.funcexpr().args())
+ ret = std::max(exprTypeMod(arg), ret);
+ return ret;
+ } else if (expr.has_distinctexpr()) {
+ for (auto arg : expr.funcexpr().args())
+ ret = std::max(exprTypeMod(arg), ret);
+ return ret;
+ }
+
+ if (expr.has_nulltest() || expr.has_boolexpr() || expr.has_booltest() ||
+ expr.has_caseexpr()) {
+ return -1;
+ } else {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "PlanNodeUtil::exprTypeMod expr %d not supported", expr.type());
+ }
+ }
+
+ static dbcommon::TypeKind typeKindMapping(int32_t type) {
+ dbcommon::TypeKind typeKind = static_cast<dbcommon::TypeKind>(type);
+ if (typeKind == dbcommon::TypeKind::DECIMALID)
+ typeKind = dbcommon::TypeKind::DECIMALNEWID;
+ return typeKind;
+ }
+
+ static dbcommon::FuncKind funcKindMapping(int32_t funcType) {
+ return static_cast<dbcommon::FuncKind>(funcType);
+ }
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_UTIL_H_
diff --git a/depends/univplan/src/univplan/common/plannode-walker.h b/depends/univplan/src/univplan/common/plannode-walker.h
new file mode 100644
index 0000000..46f4551
--- /dev/null
+++ b/depends/univplan/src/univplan/common/plannode-walker.h
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_WALKER_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_WALKER_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+
+#include "dbcommon/log/logger.h"
+
+namespace univplan {
+
+class PlanNodeWalkerContext {
+ public:
+ PlanNodeWalkerContext() {}
+ virtual ~PlanNodeWalkerContext() {}
+};
+
+class PlanNodeWalker {
+ public:
+ PlanNodeWalker() {}
+ virtual ~PlanNodeWalker() {}
+
+ virtual void walk(UnivPlanExprPoly *expr, PlanNodeWalkerContext *ctx) = 0;
+
+ // Walk all dependent expressions.
+ // @param expr Root expr
+ // @param walker Apply walker->walk() for checking each expression
+ // @param ctx Context for checking list
+ static void walkExpressionTree(UnivPlanExprPoly *expr, PlanNodeWalker *walker,
+ PlanNodeWalkerContext *ctx) {
+ // Call walkExpressionTree to check all containing "UnivPlanExprPoly".
+ // Pay attention to check the "optional UnivPlanExprPoly" exist before
+ // calling walkExpressionTree.
+ if (expr->has_var() || expr->has_val() || expr->has_param()) {
+ // do nothing
+ } else if (expr->has_aggref()) {
+ UnivPlanAggref *aggref = expr->mutable_aggref();
+ walkExpressionTree(aggref->mutable_args(), walker, ctx);
+ } else if (expr->has_funcexpr()) {
+ UnivPlanFuncExpr *funcExpr = expr->mutable_funcexpr();
+ walkExpressionTree(funcExpr->mutable_args(), walker, ctx);
+ } else if (expr->has_opexpr()) {
+ UnivPlanOpExpr *opExpr = expr->mutable_opexpr();
+ walkExpressionTree(opExpr->mutable_args(), walker, ctx);
+ } else if (expr->has_boolexpr()) {
+ UnivPlanBoolExpr *boolExpr = expr->mutable_boolexpr();
+ walkExpressionTree(boolExpr->mutable_args(), walker, ctx);
+ } else if (expr->has_nulltest()) {
+ UnivPlanNullTest *nullTest = expr->mutable_nulltest();
+ walkExpressionTree(nullTest->mutable_arg(), walker, ctx);
+ } else if (expr->has_booltest()) {
+ UnivPlanBooleanTest *boolTest = expr->mutable_booltest();
+ walkExpressionTree(boolTest->mutable_arg(), walker, ctx);
+ } else if (expr->has_targetentry()) {
+ UnivPlanTargetEntry *targetEntry = expr->mutable_targetentry();
+ walkExpressionTree(targetEntry->mutable_expression(), walker, ctx);
+ } else if (expr->has_caseexpr()) {
+ UnivPlanCaseExpr *caseexpr = expr->mutable_caseexpr();
+ walkExpressionTree(caseexpr->mutable_args(), walker, ctx);
+ walkExpressionTree(caseexpr->mutable_defresult(), walker, ctx);
+ } else if (expr->has_casewhen()) {
+ UnivPlanCaseWhen *casewhen = expr->mutable_casewhen();
+ walkExpressionTree(casewhen->mutable_expr(), walker, ctx);
+ walkExpressionTree(casewhen->mutable_result(), walker, ctx);
+ } else if (expr->has_subplan()) {
+ UnivPlanSubPlan *subplan = expr->mutable_subplan();
+ walkExpressionTree(subplan->mutable_args(), walker, ctx);
+ if (subplan->has_testexpr())
+ walkExpressionTree(subplan->mutable_testexpr(), walker, ctx);
+ } else if (expr->has_scalararrayopexpr()) {
+ UnivPlanScalarArrayOpExpr *scalarArrayOpExpr =
+ expr->mutable_scalararrayopexpr();
+ walkExpressionTree(scalarArrayOpExpr->mutable_args(), walker, ctx);
+ } else if (expr->has_coalesceexpr()) {
+ UnivPlanCoalesceExpr *coalesceExpr = expr->mutable_coalesceexpr();
+ walkExpressionTree(coalesceExpr->mutable_args(), walker, ctx);
+ } else if (expr->has_nullifexpr()) {
+ UnivPlanNullIfExpr *nullIfExpr = expr->mutable_nullifexpr();
+ walkExpressionTree(nullIfExpr->mutable_args(), walker, ctx);
+ } else if (expr->has_distinctexpr()) {
+ UnivPlanDistinctExpr *distinctExpr = expr->mutable_distinctexpr();
+ walkExpressionTree(distinctExpr->mutable_args(), walker, ctx);
+ } else {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "PlanNodeUtil::expressionTreeWalker expr %d not supported",
+ expr->type());
+ }
+ walker->walk(expr, ctx);
+ }
+
+ static void walkExpressionTree(UnivPlanExprPolyList *exprs,
+ PlanNodeWalker *walker,
+ PlanNodeWalkerContext *ctx) {
+ for (int i = 0; i < exprs->size(); ++i) {
+ walkExpressionTree(exprs->Mutable(i), walker, ctx);
+ }
+ }
+
+ virtual void walk(UnivPlanPlanNodePoly *planNodePoly, PlanNodeWalker *walker,
+ PlanNodeWalkerContext *ctx) {}
+
+ static void walkPlanTree(UnivPlanPlanNodePoly *planNodePoly,
+ PlanNodeWalker *walker, PlanNodeWalkerContext *ctx) {
+ auto planNode = PlanNodeUtil::getMutablePlanNode(planNodePoly);
+ if (planNode->has_leftplan())
+ walkPlanTree(planNode->mutable_leftplan(), walker, ctx);
+ if (planNode->has_rightplan())
+ walkPlanTree(planNode->mutable_rightplan(), walker, ctx);
+ if (planNodePoly->has_append()) {
+ auto append = planNodePoly->mutable_append();
+ for (auto i = 0; i < append->appendplans_size(); i++)
+ walkPlanTree(append->mutable_appendplans(i), walker, ctx);
+ }
+
+ walker->walk(planNodePoly, walker, ctx);
+ }
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_PLANNODE_WALKER_H_
diff --git a/depends/univplan/src/univplan/common/stagize.cc b/depends/univplan/src/univplan/common/stagize.cc
new file mode 100644
index 0000000..bfa8d50
--- /dev/null
+++ b/depends/univplan/src/univplan/common/stagize.cc
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/common/stagize.h"
+
+#include <utility>
+
+#include "dbcommon/log/logger.h"
+#include "univplan/common/plannode-util.h"
+#include "univplan/common/subplan-util.h"
+
+namespace univplan {
+
+// return a totally new Plan inside ctx->upb
+void PlanStagizer::stagize(const UnivPlanPlan *plan, StagizerContext *ctx) {
+ ctx->upb.reset(new UnivPlanBuilder);
+ ctx->upb->getPlanBuilderPlan()->from(*plan);
+
+ // stage main plan
+ ctx->pid = -1;
+ ctx->isleft = true;
+ stageNo = 0;
+ // -1 is a mark for the root stage, the stageNo of the plan tree's stage
+ // is a postorder traversal except that the stageNo of root stage is zero
+ ctx->upb->getPlanBuilderPlan()->setStageNo(-1);
+ stagize(plan->plan(), ctx, 0);
+ ctx->upb->getPlanBuilderPlan()->setStageNo(0);
+
+ // stage subplan
+ for (auto i = 0; i < plan->subplans_size(); i++) {
+ ctx->pid = -1;
+ ctx->isleft = true;
+ if (ctx->subplanStageNo[i + 1] <= ctx->totalStageNo) {
+ // retrieve stageNo for SubPlan
+ stagize(plan->subplans(i), ctx, ctx->subplanStageNo[i + 1]);
+ } else {
+ // allocate new stage for InitPlan
+ auto newStage =
+ ctx->upb->getPlanBuilderPlan()->addChildStageAndGetBuilder();
+ newStage->from(*(ctx->upb->getPlanBuilderPlan()->getPlan()));
+ newStage->setStageNo(ctx->subplanStageNo[i + 1]);
+ auto backupStage = ctx->upb->swapBuilder(std::move(newStage));
+ stagize(plan->subplans(i), ctx, ctx->subplanStageNo[i + 1]);
+ ctx->upb->swapBuilder(std::move(backupStage));
+ ctx->upb->getPlanBuilderPlan()->getPlan()->add_subplans(); // placeholder
+ }
+ }
+ assert(ctx->subplanStageNo.size() == plan->subplans_size());
+
+ // link subplan to correlated stage
+ auto rootPlan = ctx->upb->getPlanBuilderPlan()->getPlan();
+ assert(rootPlan->subplans_size() == plan->subplans_size());
+ auto rootStage = rootPlan;
+ UnivPlanPlan backup; // store stagized subplans
+ backup.mutable_subplans()->Swap(rootPlan->mutable_subplans());
+ SubplanUtil::linkSubplan(&backup, rootStage);
+}
+
+// FIXME(chiyang): To support subplan with correct stageNo(i.e. the
+// corresponding sliceID/MotionID in HAWQ), we copy the motionID from HAWQ.
+// However, motionID is not set in previous unittest, as a result of which we
+// keep the old stageNo allocate strategy when needed(i.e. when the
+// connector.stageno() == -1).
+void PlanStagizer::stagize(const UnivPlanPlanNodePoly &originalNode,
+ StagizerContext *ctx, int32_t currentStageNo) {
+ // ctx->upb->getPlanBuilderPlan referred to the current stage
+ // ctx->pid referred to the pid of the new plan tree
+ // ctx->isleft determine whether the current plannode is the left child of its
+ // parent
+ if (!originalNode.IsInitialized()) {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "stagize node is empty");
+ }
+ const UnivPlanPlan *currentStage = ctx->upb->getPlanBuilderPlan()->getPlan();
+ if (originalNode.has_connector()) {
+ const UnivPlanConnector &connector = originalNode.connector();
+
+ UnivPlanBuilderSinkInput::uptr builderSinkInput;
+ switch (connector.type()) {
+ case CONNECTORTYPE_CONVERGE:
+ builderSinkInput.reset(new UnivPlanBuilderConverge());
+ break;
+ case CONNECTORTYPE_SHUFFLE:
+ builderSinkInput.reset(new UnivPlanBuilderShuffle());
+ break;
+ case CONNECTORTYPE_BROADCAST:
+ builderSinkInput.reset(new UnivPlanBuilderBroadcast());
+ break;
+ default:
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "unexpected connector node type %d",
+ connector.type());
+ }
+ // build sink
+ UnivPlanBuilderSink::uptr builderSink(new UnivPlanBuilderSink());
+ builderSink->from(connector);
+ builderSink->setSourceStageNo(stageNo);
+ builderSink->setCurrentStageNo(currentStage->stageno());
+ builderSink->setConnectorType(connector.type());
+ builderSink->uid = nodeId++;
+ builderSink->pid = ctx->pid;
+ UnivPlanBuilderSink *backupBuilderSink = builderSink.get();
+ ctx->upb->addPlanNode(ctx->isleft, std::move(builderSink));
+
+ // build new stage, need to be done before add sinkinput
+ UnivPlanBuilderPlan::uptr builderNewStage =
+ ctx->upb->getPlanBuilderPlan()->addChildStageAndGetBuilder();
+ builderNewStage->from(*(ctx->upb->getPlanBuilderPlan()->getPlan()));
+ builderNewStage->setStageNo(connector.stageno() != -1 ? connector.stageno()
+ : stageNo);
+
+ UnivPlanBuilderPlan::uptr backupStage =
+ ctx->upb->swapBuilder(std::move(builderNewStage));
+
+ // sinkInput info
+ builderSinkInput->from(connector);
+ builderSinkInput->setTargetStageNo(currentStage->stageno());
+ builderSinkInput->setCurrentStageNo(stageNo);
+ builderSinkInput->uid = nodeId++;
+ builderSinkInput->pid = -1;
+ UnivPlanBuilderSinkInput *backupBuilderSinkInput = builderSinkInput.get();
+ ctx->upb->addPlanNode(ctx->isleft, std::move(builderSinkInput));
+
+ // sinkinput's left child comes from connector,
+ // and there will be only one child
+ const UnivPlanPlanNodePoly &originalNodeLeft =
+ PlanNodeUtil::getPlanNode(originalNode).leftplan();
+ ctx->pid = nodeId - 1; // the nodeId of sinkinput
+ ctx->isleft = true;
+ stageNo++;
+ stagize(originalNodeLeft, ctx, connector.stageno());
+
+ builderNewStage = ctx->upb->swapBuilder(std::move(backupStage));
+
+ // the old stageNo assign strategy, a post-order traversal
+ int32_t childStageNo =
+ ctx->totalStageNo - builderNewStage->getPlan()->stageno();
+ if (currentStageNo == -1)
+ currentStageNo =
+ (backupBuilderSinkInput->getTargetStageNo() != -1)
+ ? (ctx->totalStageNo - backupBuilderSinkInput->getTargetStageNo())
+ : 0;
+ // to bypass the old stageNo assign strategy when possible
+ if (connector.stageno() != -1) {
+ childStageNo = connector.stageno();
+ if (currentStageNo == -1) currentStageNo = currentStage->stageno();
+ if (currentStageNo == -1) currentStageNo = 0;
+ }
+
+ builderNewStage->setStageNo(childStageNo);
+ backupBuilderSink->setCurrentStageNo(currentStageNo);
+ backupBuilderSink->setSourceStageNo(childStageNo);
+ backupBuilderSinkInput->setCurrentStageNo(childStageNo);
+ backupBuilderSinkInput->setTargetStageNo(currentStageNo);
+ } else {
+ UnivPlanBuilderNode::uptr builderNodeNew =
+ PlanNodeUtil::createPlanBuilderNode(originalNode.type());
+ builderNodeNew->from(originalNode);
+ int32_t builderNodeNewId = nodeId++;
+ builderNodeNew->uid = builderNodeNewId;
+ builderNodeNew->pid = ctx->pid;
+ ctx->upb->addPlanNode(ctx->isleft, std::move(builderNodeNew));
+
+ const UnivPlanPlanNode &originalNodePlanNode =
+ PlanNodeUtil::getPlanNode(originalNode);
+
+ auto relatedSubplans = SubplanUtil::getRelatedSubplanIds(originalNode);
+ for (auto subplanId : relatedSubplans) {
+ ctx->subplanStageNo[subplanId] = currentStageNo;
+ }
+
+ if (originalNodePlanNode.has_rightplan()) {
+ ctx->pid = builderNodeNewId;
+ ctx->isleft = false;
+ const UnivPlanPlanNodePoly &originalNodeRight =
+ originalNodePlanNode.rightplan();
+ stagize(originalNodeRight, ctx, currentStageNo);
+ }
+
+ if (originalNodePlanNode.has_leftplan()) {
+ ctx->pid = builderNodeNewId;
+ ctx->isleft = true;
+ const UnivPlanPlanNodePoly &originalNodeLeft =
+ originalNodePlanNode.leftplan();
+ stagize(originalNodeLeft, ctx, currentStageNo);
+ }
+
+ if (originalNode.has_subqueryscan()) {
+ ctx->pid = builderNodeNewId;
+ ctx->isleft = true;
+ const UnivPlanPlanNodePoly &subplan =
+ originalNode.subqueryscan().subplan();
+ stagize(subplan, ctx, currentStageNo);
+ }
+ }
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/common/stagize.h b/depends/univplan/src/univplan/common/stagize.h
new file mode 100644
index 0000000..6f0b056
--- /dev/null
+++ b/depends/univplan/src/univplan/common/stagize.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_STAGIZE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_STAGIZE_H_
+
+#include <map>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder.h"
+
+namespace univplan {
+
+typedef struct StagizerContext {
+ UnivPlanBuilder::uptr upb;
+ int32_t pid;
+ bool isleft;
+ uint32_t totalStageNo;
+ std::map<int32_t, int32_t> subplanStageNo;
+} StagizerContext;
+
+class PlanStagizer {
+ public:
+ PlanStagizer() {}
+ ~PlanStagizer() {}
+
+ void stagize(const UnivPlanPlan *plan, StagizerContext *ctx);
+
+ private:
+ void stagize(const UnivPlanPlanNodePoly &node, StagizerContext *ctx,
+ int32_t currentStageNo);
+ int32_t nodeId = 0;
+ int32_t stageNo = 0; // stageNo start from 0
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_STAGIZE_H_
diff --git a/depends/univplan/src/univplan/common/statistics.h b/depends/univplan/src/univplan/common/statistics.h
new file mode 100644
index 0000000..3090918
--- /dev/null
+++ b/depends/univplan/src/univplan/common/statistics.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_STATISTICS_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_STATISTICS_H_
+
+namespace univplan {
+// Statistics that are available for all types of columns.
+class ColumnStatistics {
+ public:
+ virtual ~ColumnStatistics() {}
+
+ // Get the number of values in this column. It will differ from the number
+ // of rows because of NULL values and repeated values.
+ // @return the number of values
+ uint64_t getNumberOfValues() const { return valueCount; }
+
+ // Returns true if there are nulls in the scope of column statistics
+ bool hasNull() const { return hasNullValue; }
+
+ virtual void reset() {
+ valueCount = 0;
+ hasNullValue = true;
+ }
+
+ void increment(uint64_t count) { valueCount += count; }
+
+ void unsetNull() { hasNullValue = false; }
+
+ virtual void merge(const ColumnStatistics& stats) {
+ valueCount += stats.getNumberOfValues();
+ hasNullValue |= stats.hasNull();
+ }
+
+ protected:
+ uint64_t valueCount;
+ bool hasNullValue;
+};
+
+class Statistics {
+ public:
+ virtual ~Statistics() {}
+
+ // Get the statistics of colId column.
+ // @return one column's statistics
+ virtual const ColumnStatistics* getColumnStatistics(uint32_t colId) const = 0;
+
+ // Get the number of columns
+ // @return the number of columns
+ virtual uint32_t getNumberOfColumns() const = 0;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_STATISTICS_H_
diff --git a/depends/univplan/src/univplan/common/subplan-util.cc b/depends/univplan/src/univplan/common/subplan-util.cc
new file mode 100644
index 0000000..b7e9fe7
--- /dev/null
+++ b/depends/univplan/src/univplan/common/subplan-util.cc
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/common/subplan-util.h"
+#include "univplan/common/plannode-util.h"
+#include "univplan/common/plannode-walker.h"
+
+namespace univplan {
+
+class SubplanWalker : public PlanNodeWalker {
+ public:
+ void walk(UnivPlanPlanNodePoly* planNodePoly, PlanNodeWalker* walker,
+ PlanNodeWalkerContext* ctx) override {
+ auto planNode = PlanNodeUtil::getMutablePlanNode(planNodePoly);
+
+ // Basic check
+ PlanNodeWalker::walkExpressionTree(planNode->mutable_targetlist(), walker,
+ ctx);
+ PlanNodeWalker::walkExpressionTree(planNode->mutable_quallist(), walker,
+ ctx);
+ PlanNodeWalker::walkExpressionTree(planNode->mutable_initplan(), walker,
+ ctx);
+
+ // Special check for shuffle
+ if (planNodePoly->has_shuffle()) {
+ auto sf = planNodePoly->mutable_shuffle();
+ PlanNodeWalker::walkExpressionTree(sf->mutable_hashexpr(), walker, ctx);
+ }
+
+ // Special check for joinQual
+ if (planNodePoly->has_nestloop()) {
+ auto nl = planNodePoly->mutable_nestloop();
+ PlanNodeWalker::walkExpressionTree(nl->mutable_joinqual(), walker, ctx);
+ }
+ if (planNodePoly->has_hashjoin()) {
+ auto hj = planNodePoly->mutable_hashjoin();
+ PlanNodeWalker::walkExpressionTree(hj->mutable_joinqual(), walker, ctx);
+ PlanNodeWalker::walkExpressionTree(hj->mutable_hashclauses(), walker,
+ ctx);
+ PlanNodeWalker::walkExpressionTree(hj->mutable_hashqualclauses(), walker,
+ ctx);
+ }
+ if (planNodePoly->has_mergejoin()) {
+ auto mj = planNodePoly->mutable_mergejoin();
+ PlanNodeWalker::walkExpressionTree(mj->mutable_joinqual(), walker, ctx);
+ PlanNodeWalker::walkExpressionTree(mj->mutable_mergeclauses(), walker,
+ ctx);
+ }
+
+ // Special check for limit
+ if (planNodePoly->has_limit()) {
+ auto limit = planNodePoly->mutable_limit();
+ if (limit->has_limitoffset())
+ PlanNodeWalker::walkExpressionTree(limit->mutable_limitoffset(), walker,
+ ctx);
+ if (limit->has_limitcount())
+ PlanNodeWalker::walkExpressionTree(limit->mutable_limitcount(), walker,
+ ctx);
+ }
+ if (planNodePoly->has_sort()) {
+ auto sort = planNodePoly->mutable_sort();
+ if (sort->has_limitoffset())
+ PlanNodeWalker::walkExpressionTree(sort->mutable_limitoffset(), walker,
+ ctx);
+ if (sort->has_limitcount())
+ PlanNodeWalker::walkExpressionTree(sort->mutable_limitcount(), walker,
+ ctx);
+ }
+
+ // Special check from result
+ if (planNodePoly->has_result()) {
+ auto result = planNodePoly->mutable_result();
+ PlanNodeWalker::walkExpressionTree(result->mutable_resconstantqual(),
+ walker, ctx);
+ }
+ }
+};
+
+class SubplanPlanidWalkerContext : public PlanNodeWalkerContext {
+ public:
+ std::vector<int32_t> planids;
+};
+
+class SubplanPlanidWalker : public SubplanWalker {
+ public:
+ void walk(UnivPlanExprPoly* expr, PlanNodeWalkerContext* ctx) override {
+ if (expr->has_subplan() && !expr->subplan().initplan()) {
+ SubplanPlanidWalkerContext* context =
+ reinterpret_cast<SubplanPlanidWalkerContext*>(ctx);
+ context->planids.push_back(expr->subplan().planid());
+ }
+ }
+};
+
+std::vector<int32_t> SubplanUtil::getRelatedSubplanIds(
+ const UnivPlanPlanNodePoly& planNodePolyInput) {
+ SubplanPlanidWalkerContext ctx;
+ SubplanPlanidWalker walker;
+ walker.SubplanWalker::walk(
+ &(const_cast<UnivPlanPlanNodePoly&>(planNodePolyInput)), &walker, &ctx);
+ return ctx.planids;
+}
+
+class SubplanAttachWalkerContext : public PlanNodeWalkerContext {
+ public:
+ const UnivPlanPlan* rootPlan;
+ UnivPlanPlan* currStage;
+};
+
+class SubplanAttachWalker : public SubplanWalker {
+ public:
+ void walk(UnivPlanExprPoly* expr, PlanNodeWalkerContext* ctx) override {
+ if (expr->has_subplan() && !expr->subplan().initplan()) {
+ auto context = reinterpret_cast<SubplanAttachWalkerContext*>(ctx);
+ // count plan ID from 1
+ auto oldPlanId = expr->subplan().planid();
+ context->currStage->add_subplans()->CopyFrom(
+ context->rootPlan->subplans(oldPlanId - 1));
+ expr->mutable_subplan()->set_planid(context->currStage->subplans_size());
+ }
+ }
+};
+
+void SubplanUtil::linkSubplan(UnivPlanPlan* rootPlan, UnivPlanPlan* currStage) {
+ SubplanAttachWalker walker;
+ SubplanAttachWalkerContext ctx;
+ ctx.rootPlan = rootPlan;
+ ctx.currStage = currStage;
+ PlanNodeWalker::walkPlanTree(currStage->mutable_plan(), &walker, &ctx);
+ for (auto i = 0; i < currStage->childstages_size(); i++) {
+ linkSubplan(rootPlan, currStage->mutable_childstages(i));
+ }
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/common/subplan-util.h b/depends/univplan/src/univplan/common/subplan-util.h
new file mode 100644
index 0000000..8c1c942
--- /dev/null
+++ b/depends/univplan/src/univplan/common/subplan-util.h
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_SUBPLAN_UTIL_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_SUBPLAN_UTIL_H_
+
+#include <vector>
+
+#include "univplan/common/univplan-type.h"
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class SubplanUtil {
+ public:
+ // @return Return related subplan IDs.
+ static std::vector<int32_t> getRelatedSubplanIds(
+ const UnivPlanPlanNodePoly& planNodePolyInput);
+
+ // Link subplan to its correlated plan stage.
+ // Inside stage, each subplan expression will change its planId to a
+ // new number according to the order of attaching subplans.
+ //
+ // @param rootPlan The plan that contains fully stagized subplans.
+ static void linkSubplan(UnivPlanPlan* rootPlan, UnivPlanPlan* currStage);
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_SUBPLAN_UTIL_H_
diff --git a/depends/univplan/src/univplan/common/univplan-type.h b/depends/univplan/src/univplan/common/univplan-type.h
new file mode 100644
index 0000000..b38f61d
--- /dev/null
+++ b/depends/univplan/src/univplan/common/univplan-type.h
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_UNIVPLAN_TYPE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_UNIVPLAN_TYPE_H_
+
+#include <list>
+#include <string>
+
+#include "dbcommon/common/tuple-batch.h"
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-scan-task.h"
+
+namespace univplan {
+typedef google::protobuf::RepeatedPtrField<univplan::UnivPlanExprPoly>
+ UnivPlanExprPolyList;
+
+typedef google::protobuf::RepeatedPtrField<univplan::UnivPlanScanTask>
+ UnivPlanScanTaskList;
+
+// this class provides interface of accessing scan task and its splits
+class UnivPlanScanFileSplitList {
+ public:
+ UnivPlanScanFileSplitList() : splitsTb_(nullptr) {}
+ explicit UnivPlanScanFileSplitList(dbcommon::TupleBatch *tb)
+ : splitsTb_(tb) {}
+
+ void setSplitsTb(dbcommon::TupleBatch *tb) { splitsTb_ = tb; }
+ uint32_t splits_size() const {
+ return splitsTb_ == nullptr ? 0 : splitsTb_->getNumOfRows();
+ }
+
+ // methods of getting split properties indexed in tb
+ void splits_filename(int index, std::string *filename) {
+ const dbcommon::TupleBatchReader &readers =
+ splitsTb_->getTupleBatchReader();
+ uint64_t len = 0;
+ bool isNull = false;
+ const char *res =
+ readers[TBSPLITS_COL_INDEX_FILENAME]->read(index, &len, &isNull);
+ filename->assign(res, len);
+ }
+
+ int64_t splits_start(int index) const {
+ const dbcommon::TupleBatchReader &readers =
+ splitsTb_->getTupleBatchReader();
+ uint64_t len = 0;
+ bool isNull = false;
+ const char *res =
+ readers[TBSPLITS_COL_INDEX_START]->read(index, &len, &isNull);
+ return *(reinterpret_cast<const int64_t *>(res));
+ }
+
+ int64_t splits_len(int index) const {
+ const dbcommon::TupleBatchReader &readers =
+ splitsTb_->getTupleBatchReader();
+ uint64_t len = 0;
+ bool isNull = false;
+ const char *res =
+ readers[TBSPLITS_COL_INDEX_LEN]->read(index, &len, &isNull);
+ return *(reinterpret_cast<const int64_t *>(res));
+ }
+
+ int64_t splits_rangeid(int index) const {
+ const dbcommon::TupleBatchReader &readers =
+ splitsTb_->getTupleBatchReader();
+ uint64_t len = 0;
+ bool isNull = false;
+ const char *res =
+ readers[TBSPLITS_COL_INDEX_RANGEID]->read(index, &len, &isNull);
+ return *(reinterpret_cast<const int64_t *>(res));
+ }
+
+ int32_t splits_rgid(int index) const {
+ const dbcommon::TupleBatchReader &readers =
+ splitsTb_->getTupleBatchReader();
+ uint64_t len = 0;
+ bool isNull = false;
+ const char *res =
+ readers[TBSPLITS_COL_INDEX_RGID]->read(index, &len, &isNull);
+ return *(reinterpret_cast<const int32_t *>(res));
+ }
+
+ void debugOuput() {
+ if (splitsTb_ == nullptr) {
+ LOG_INFO("no rows in splits tb");
+ return;
+ }
+ for (int i = 0; i < splitsTb_->getNumOfRows(); ++i) {
+ std::string filename;
+ splits_filename(i, &filename);
+ int64_t start = splits_start(i);
+ int64_t len = splits_len(i);
+ int64_t rangeid = splits_rangeid(i);
+ int32_t rgid = splits_rgid(i);
+ LOG_INFO("[%d] %s,%lld,%lld,%lld,%d", i, filename.c_str(), start, len,
+ rangeid, rgid);
+ }
+ }
+
+ protected:
+ dbcommon::TupleBatch *splitsTb_;
+};
+
+// this subclass owns deserialized tb
+class UnivPlanScanFileSplitListTb : public UnivPlanScanFileSplitList {
+ public:
+ UnivPlanScanFileSplitListTb() : UnivPlanScanFileSplitList(nullptr) {}
+ explicit UnivPlanScanFileSplitListTb(dbcommon::TupleBatch::uptr tb)
+ : UnivPlanScanFileSplitList(tb.get()) {
+ splitsTbInst_ = std::move(tb);
+ }
+ void deserialize(const std::string &serializedTb) {
+ splitsTbInst_.reset(new dbcommon::TupleBatch());
+ splitsTbInst_->deserialize(serializedTb);
+ setSplitsTb(splitsTbInst_.get());
+ }
+
+ protected:
+ std::unique_ptr<dbcommon::TupleBatch> splitsTbInst_;
+};
+
+typedef std::list<std::unique_ptr<univplan::UnivPlanScanFileSplitList>>
+ UnivPlanScanFileSplitListList;
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_UNIVPLAN_TYPE_H_
diff --git a/depends/univplan/src/univplan/common/var-util.cc b/depends/univplan/src/univplan/common/var-util.cc
new file mode 100644
index 0000000..e31be79
--- /dev/null
+++ b/depends/univplan/src/univplan/common/var-util.cc
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/common/var-util.h"
+
+#include <utility>
+
+#include "dbcommon/log/logger.h"
+#include "dbcommon/utils/macro.h"
+
+#include "univplan/common/plannode-util.h"
+#include "univplan/common/plannode-walker.h"
+
+namespace univplan {
+
+class FixVarTypeContext : public PlanNodeWalkerContext {
+ public:
+ FixVarTypeContext() {}
+ virtual ~FixVarTypeContext() {}
+
+ public:
+ UnivPlanPlanNode* planNode = nullptr;
+};
+
+class FixVarTypeWalker : public PlanNodeWalker {
+ public:
+ void walk(UnivPlanExprPoly* expr, PlanNodeWalkerContext* ctx) override {
+ if (expr->has_var()) {
+ FixVarTypeContext* context = reinterpret_cast<FixVarTypeContext*>(ctx);
+ UnivPlanPlanNode* planNode = context->planNode;
+ UnivPlanVar* var = expr->mutable_var();
+ if (var->varno() == OUTER_VAR && planNode->has_leftplan()) {
+ UnivPlanPlanNode* leftPlanNode =
+ PlanNodeUtil::getMutablePlanNode(planNode->mutable_leftplan());
+ UnivPlanExprPoly* refTargetEntry =
+ leftPlanNode->mutable_targetlist(var->varattno() - 1);
+ var->set_typeid_(
+ static_cast<int32_t>(PlanNodeUtil::exprType(*refTargetEntry)));
+ } else if (var->varno() == INNER_VAR && planNode->has_rightplan()) {
+ UnivPlanPlanNode* rightPlanNode =
+ PlanNodeUtil::getMutablePlanNode(planNode->mutable_rightplan());
+ UnivPlanExprPoly* refTargetEntry =
+ rightPlanNode->mutable_targetlist(var->varattno() - 1);
+ var->set_typeid_(
+ static_cast<int32_t>(PlanNodeUtil::exprType(*refTargetEntry)));
+ }
+ }
+ }
+};
+
+void VarUtil::fixVarType(UnivPlanPlanNodePoly* plantree) {
+ UnivPlanPlanNode* planNode = PlanNodeUtil::getMutablePlanNode(plantree);
+
+ // workaround here
+ if (plantree->type() == UNIVPLAN_APPEND) return;
+
+ if (planNode->has_leftplan()) fixVarType(planNode->mutable_leftplan());
+ if (planNode->has_rightplan()) fixVarType(planNode->mutable_rightplan());
+ FixVarTypeContext walkerContext;
+ walkerContext.planNode = planNode;
+ FixVarTypeWalker walker;
+
+ PlanNodeWalker::walkExpressionTree(planNode->mutable_targetlist(), &walker,
+ &walkerContext);
+}
+
+class CollectVarTypeContext : public PlanNodeWalkerContext {
+ public:
+ CollectVarTypeContext() {}
+ virtual ~CollectVarTypeContext() {}
+
+ public:
+ std::vector<int32_t> varAttNoVec;
+};
+
+class CollectVarTypeWalker : public PlanNodeWalker {
+ public:
+ void walk(UnivPlanExprPoly* expr, PlanNodeWalkerContext* ctx) override {
+ if (expr->has_var()) {
+ CollectVarTypeContext* context =
+ reinterpret_cast<CollectVarTypeContext*>(ctx);
+ context->varAttNoVec.push_back(expr->var().varattno());
+ }
+ }
+};
+
+std::vector<int32_t> VarUtil::collectVarAttNo(UnivPlanExprPoly* expr) {
+ CollectVarTypeContext walkerContext;
+ CollectVarTypeWalker walker;
+
+ PlanNodeWalker::walkExpressionTree(expr, &walker, &walkerContext);
+ return std::move(walkerContext.varAttNoVec);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/common/var-util.h b/depends/univplan/src/univplan/common/var-util.h
new file mode 100644
index 0000000..c185e38
--- /dev/null
+++ b/depends/univplan/src/univplan/common/var-util.h
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_COMMON_VAR_UTIL_H_
+#define UNIVPLAN_SRC_UNIVPLAN_COMMON_VAR_UTIL_H_
+
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class VarUtil {
+ public:
+ VarUtil() {}
+ ~VarUtil() {}
+
+ void fixVarType(UnivPlanPlanNodePoly* plantree);
+ std::vector<int32_t> collectVarAttNo(UnivPlanExprPoly* expr);
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_COMMON_VAR_UTIL_H_
diff --git a/depends/univplan/src/univplan/cwrapper/univplan-c.cc b/depends/univplan/src/univplan/cwrapper/univplan-c.cc
new file mode 100644
index 0000000..0bce15e
--- /dev/null
+++ b/depends/univplan/src/univplan/cwrapper/univplan-c.cc
@@ -0,0 +1,1172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/cwrapper/univplan-c.h"
+
+#include <cassert>
+#include <map>
+#include <stack>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "dbcommon/function/func-kind.cg.h"
+#include "dbcommon/function/func.h"
+#include "dbcommon/log/logger.h"
+#include "dbcommon/utils/comp/lz4-compressor.h"
+#include "dbcommon/utils/macro.h"
+
+#include "univplan/common/plannode-util.h"
+#include "univplan/common/stagize.h"
+#include "univplan/common/var-util.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-tree.h"
+#include "univplan/univplanbuilder/univplanbuilder-plan.h"
+#include "univplan/univplanbuilder/univplanbuilder-table.h"
+#include "univplan/univplanbuilder/univplanbuilder.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static void univPlanSetError(UnivPlanCatchedError *ce, int errCode,
+ const char *errMsg);
+
+struct UnivPlanC {
+ univplan::UnivPlanBuilder::uptr upb;
+ std::stack<univplan::UnivPlanBuilder::uptr> upbBak;
+ univplan::UnivPlanBuilderNode::uptr curNode;
+ std::stack<univplan::UnivPlanBuilderNode::uptr> curNodeBak;
+ univplan::UnivPlanBuilderExprTree::uptr curExpr;
+ std::string serializedPlan;
+ UnivPlanCatchedError error;
+ std::string debugString;
+ uint16_t totalStageNo;
+ std::map<int32_t, int32_t> subplanStageNo;
+};
+
+UnivPlanC *univPlanNewInstance() {
+ UnivPlanC *instance = new UnivPlanC();
+ instance->upb.reset(new univplan::UnivPlanBuilder);
+ instance->error.errCode = ERRCODE_SUCCESSFUL_COMPLETION;
+ instance->totalStageNo = 0;
+ return instance;
+}
+
+void univPlanFreeInstance(UnivPlanC **up) {
+ assert(up != nullptr);
+ if (*up == nullptr) return;
+ delete *up;
+ *up = nullptr;
+}
+
+void univPlanNewSubPlanNode(UnivPlanC *up) {
+ up->upbBak.push(std::move(up->upb));
+ up->curNodeBak.push(std::move(up->curNode));
+ up->upb.reset(new univplan::UnivPlanBuilder);
+}
+
+void univPlanFreeSubPlanNode(UnivPlanC *up) {
+ up->upb = std::move(up->upbBak.top());
+ up->upbBak.pop();
+ up->curNode = std::move(up->curNodeBak.top());
+ up->curNodeBak.pop();
+}
+
+void univPlanRangeTblEntryAddTable(UnivPlanC *up, uint64_t tid,
+ FormatType format, const char *location,
+ const char *optStrInJson, uint32_t columnNum,
+ const char **columnName,
+ int32_t *columnDataType,
+ int64_t *columnDataTypeMod) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ univplan::UnivPlanBuilderRangeTblEntry::uptr rte =
+ bld->addRangeTblEntryAndGetBuilder();
+ univplan::UnivPlanBuilderTable::uptr table(
+ new univplan::UnivPlanBuilderTable);
+ table->setTableId(tid);
+ univplan::UNIVPLANFORMATTYPE fmtType;
+ switch (format) {
+ case FormatType::UnivPlanCsvFormat:
+ fmtType = univplan::CSV_FORMAT;
+ break;
+ case FormatType::UnivPlanTextFormat:
+ fmtType = univplan::TEXT_FORMAT;
+ break;
+ case FormatType::UnivPlanOrcFormat:
+ fmtType = univplan::ORC_FORMAT;
+ break;
+ case FormatType::UnivPlanMagmaFormat:
+ fmtType = univplan::MAGMA_FORMAT;
+ break;
+ default:
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "univPlanRangeTblEntryAddTable can't handle FormatType %d",
+ format);
+ }
+ table->setTableFormat(fmtType);
+ table->setTableLocation(location);
+
+ std::string cvKey = "TableOptionsInJson_" + std::to_string(tid);
+ std::string nCvKey;
+ bld->addCommonValue(cvKey, optStrInJson, &nCvKey);
+ table->setTableOptionsInJson(nCvKey);
+ for (int i = 0; i < columnNum; ++i) {
+ univplan::UnivPlanBuilderColumn::uptr column =
+ table->addPlanColumnAndGetBuilder();
+ column->setColumnName(columnName[i]);
+ column->setTypeId(columnDataType[i]);
+ column->setTypeMod(columnDataTypeMod[i]);
+ }
+
+ rte->setTable(std::move(table->ownTable()));
+}
+
+void univPlanRangeTblEntryAddDummy(UnivPlanC *up) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ univplan::UnivPlanBuilderRangeTblEntry::uptr rte =
+ bld->addRangeTblEntryAndGetBuilder();
+ univplan::UnivPlanBuilderTable::uptr table(
+ new univplan::UnivPlanBuilderTable);
+ table->setTableId(0);
+ univplan::UNIVPLANFORMATTYPE fmtType = univplan::INVALID_FORMAT;
+ table->setTableFormat(fmtType);
+ table->setTableLocation("");
+ table->setTableOptionsInJson("");
+ rte->setTable(std::move(table->ownTable()));
+}
+
+void univPlanReceiverAddListeners(UnivPlanC *up, uint32_t listenerNum,
+ const char **addr, int32_t *port) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ univplan::UnivPlanBuilderReceiver::uptr rev = bld->addReceiverAndGetBuilder();
+ for (int i = 0; i < listenerNum; ++i) {
+ univplan::UnivPlanBuilderListener::uptr listener =
+ rev->addPlanListenerAndGetBuilder();
+ listener->setAddress(addr[i]);
+ listener->setPort(port[i]);
+ }
+}
+
+void univPlanAddParamInfo(UnivPlanC *up, int32_t type, bool isNull,
+ const char *buffer) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ univplan::UnivPlanBuilderParamInfo::uptr paramInfo =
+ bld->addParamInfoAndGetBuilder();
+ paramInfo->setType(type).setIsNull(isNull);
+ if (!isNull && buffer) paramInfo->setValue(buffer);
+}
+
+void univPlanSetDoInstrument(UnivPlanC *up, bool doInstrument) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ bld->setDoInstrument(doInstrument);
+}
+
+void univPlanSetNCrossLevelParams(UnivPlanC *up, int32_t nCrossLevelParams) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ bld->setNCrossLevelParams(nCrossLevelParams);
+}
+
+void univPlanSetCmdType(UnivPlanC *up, UnivPlanCCmdType type) {
+ univplan::UnivPlanBuilderPlan *bld = up->upb->getPlanBuilderPlan();
+ univplan::UNIVPLANCMDTYPE cmdType;
+ switch (type) {
+ case UnivPlanCCmdType::UNIVPLAN_CMD_SELECT:
+ cmdType = univplan::UNIVPLANCMDTYPE::CMD_SELECT;
+ break;
+ case UnivPlanCCmdType::UNIVPLAN_CMD_INSERT:
+ cmdType = univplan::UNIVPLANCMDTYPE::CMD_INSERT;
+ break;
+ default:
+ LOG_ERROR(ERRCODE_FEATURE_NOT_SUPPORTED, "CmdType(%d) not supported yet",
+ type);
+ }
+
+ bld->setCmdType(cmdType);
+}
+
+void univPlanSetPlanNodeInfo(UnivPlanC *up, double planRows,
+ int32_t planRowWidth, uint64_t operatorMemKB) {
+ up->curNode->setNodePlanRows(planRows);
+ up->curNode->setNodePlanRowWidth(planRowWidth);
+ up->curNode->setNodePlanOperatorMemKB(operatorMemKB);
+}
+
+int32_t univPlanConnectorNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_CONNECTOR);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ up->totalStageNo += 1;
+ return up->curNode->uid;
+}
+
+void univPlanConnectorSetType(UnivPlanC *up, ConnectorType type) {
+ switch (type) {
+ case ConnectorType::UnivPlanShuffle:
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setConnectorType(univplan::CONNECTORTYPE_SHUFFLE);
+ break;
+ case ConnectorType::UnivPlanBroadcast:
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setConnectorType(univplan::CONNECTORTYPE_BROADCAST);
+ break;
+ case ConnectorType::UnivPlanConverge:
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setConnectorType(univplan::CONNECTORTYPE_CONVERGE);
+ break;
+ default:
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "univPlanConnectorSetType can't handle ConnectorType %d", type);
+ }
+}
+
+void univPlanConnectorSetStageNo(UnivPlanC *up, int32_t stageNo) {
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setStageNo(stageNo);
+}
+
+void univPlanConnectorSetRangeVsegMap(UnivPlanC *up, int *map,
+ bool magmaTable) {
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setMagmaMap(map);
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setMagmaTable(magmaTable);
+}
+
+void univPlanSetRangeNum(UnivPlanC *up, int rangeNum) {
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->setRangeNum(rangeNum);
+}
+
+void univPlanConnectorSetColIdx(UnivPlanC *up, int64_t numCols,
+ const int32_t *colIdx) {
+ univplan::UnivPlanBuilderConnector *conn =
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get());
+ std::vector<int32_t> nArray(colIdx, colIdx + numCols);
+ conn->setColIdx(nArray);
+}
+
+void univPlanConnectorSetSortFuncId(UnivPlanC *up, int64_t numCols,
+ const int32_t *sortFuncId) {
+ univplan::UnivPlanBuilderConnector *conn =
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get());
+ std::vector<int32_t> nArray(sortFuncId, sortFuncId + numCols);
+ conn->setSortFuncId(nArray);
+}
+
+int32_t univPlanExtScanNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_EXT_GS_SCAN);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanExtScanSetRelId(UnivPlanC *up, uint32_t relId) {
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->setScanRelId(relId);
+}
+
+void univPlanExtScanSetIndex(UnivPlanC *up, bool index) {
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->setScanIndex(index);
+}
+
+void univPlanExtScanSetScanType(UnivPlanC *up, int type) {
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->setIndexScanType(univplan::ExternalScanType(type));
+}
+
+void univPlanExtScanDirection(UnivPlanC *up, int direction) {
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->setDirectionType(univplan::ExternalScanDirection(direction));
+}
+
+void univPlanExtScanSetIndexName(UnivPlanC *up, const char *indexName) {
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->setIndexName(indexName);
+}
+
+void univPlanIndexQualListAddExpr(UnivPlanC *up) {
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->addIndexQual(std::move(up->curExpr));
+}
+
+void univPlanExtScanSetColumnsToRead(UnivPlanC *up, int64_t numCols,
+ const int32_t *columnsToRead) {
+ std::vector<int32_t> nArray(columnsToRead, columnsToRead + numCols);
+ dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->setColumnsToRead(nArray);
+}
+
+int32_t univPlanSeqScanNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_SCAN_SEQ);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanSeqScanSetRelId(UnivPlanC *up, uint32_t relId) {
+ dynamic_cast<univplan::UnivPlanBuilderScanSeq *>(up->curNode.get())
+ ->setScanRelId(relId);
+}
+
+void univPlanSeqScanSetColumnsToRead(UnivPlanC *up, int64_t numCols,
+ const int32_t *columnsToRead) {
+ std::vector<int32_t> nArray(columnsToRead, columnsToRead + numCols);
+ dynamic_cast<univplan::UnivPlanBuilderScanSeq *>(up->curNode.get())
+ ->setColumnsToRead(nArray);
+}
+
+void univPlanSeqScanSetReadStatsOnly(UnivPlanC *up, bool readStatsOnly) {
+ dynamic_cast<univplan::UnivPlanBuilderScanSeq *>(up->curNode.get())
+ ->setReadStatsOnly(readStatsOnly);
+}
+
+void univPlanSeqScanAddTaskWithFileSplits(bool isMagma, UnivPlanC *up,
+ uint32_t fileSplitNum,
+ const char **fileName, int64_t *start,
+ int64_t *len, int32_t *rangeid,
+ int32_t *rgid) {
+ univplan::UnivPlanBuilderScanTask::uptr task;
+ if (isMagma) {
+ task = dynamic_cast<univplan::UnivPlanBuilderExtGSScan *>(up->curNode.get())
+ ->addScanTaskAndGetBuilder();
+ } else {
+ task = dynamic_cast<univplan::UnivPlanBuilderScanSeq *>(up->curNode.get())
+ ->addScanTaskAndGetBuilder();
+ }
+ for (int i = 0; i < fileSplitNum; ++i) {
+ task->addScanFileSplit(fileName[i], start[i], len[i],
+ (rangeid == nullptr ? -1 : rangeid[i]),
+ (rgid == nullptr ? -1 : rgid[i]));
+ }
+ task->generate();
+}
+
+int32_t univPlanAggNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_AGG);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanAggSetNumGroupsAndGroupColIndexes(UnivPlanC *up, int64_t numGroups,
+ int64_t numCols,
+ const int32_t *grpColIdx) {
+ univplan::UnivPlanBuilderAgg *agg =
+ dynamic_cast<univplan::UnivPlanBuilderAgg *>(up->curNode.get());
+ agg->setNumGroups(numGroups);
+ std::vector<int32_t> nArray(grpColIdx, grpColIdx + numCols);
+ agg->setGroupColIndexes(nArray);
+}
+
+int32_t univPlanSortNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_SORT);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanSortSetColIdx(UnivPlanC *up, int64_t numCols,
+ const int32_t *colIdx) {
+ univplan::UnivPlanBuilderSort *sort =
+ dynamic_cast<univplan::UnivPlanBuilderSort *>(up->curNode.get());
+ std::vector<int32_t> nArray(colIdx, colIdx + numCols);
+ sort->setColIdx(nArray);
+}
+
+void univPlanSortSetSortFuncId(UnivPlanC *up, int64_t numCols,
+ const int32_t *sortFuncId) {
+ univplan::UnivPlanBuilderSort *sort =
+ dynamic_cast<univplan::UnivPlanBuilderSort *>(up->curNode.get());
+ std::vector<int32_t> nArray(sortFuncId, sortFuncId + numCols);
+ sort->setSortFuncId(nArray);
+}
+
+void univPlanSortAddLimitOffset(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderSort *>(up->curNode.get())
+ ->setLimitOffset(std::move(up->curExpr));
+}
+
+void univPlanSortAddLimitCount(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderSort *>(up->curNode.get())
+ ->setLimitCount(std::move(up->curExpr));
+}
+
+int32_t univPlanLimitNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_LIMIT);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+int32_t univPlanAppendNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_APPEND);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanAppendAddAppendPlan(UnivPlanC *up) {
+ const univplan::UnivPlanPlanNodePoly &poly =
+ up->upb->getPlanBuilderPlan()->getPlan()->plan();
+ dynamic_cast<univplan::UnivPlanBuilderAppend *>(up->curNodeBak.top().get())
+ ->addAppendPlan(poly);
+}
+
+static univplan::UNIVPLANJOINTYPE joinTypeMapping(UnivPlanCJoinType type) {
+ switch (type) {
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_INNER:
+ return univplan::UNIVPLANJOINTYPE::JOIN_INNER;
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_LEFT:
+ return univplan::UNIVPLANJOINTYPE::JOIN_LEFT;
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_RIGHT:
+ return univplan::UNIVPLANJOINTYPE::JOIN_RIGHT;
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_FULL:
+ return univplan::UNIVPLANJOINTYPE::JOIN_FULL;
+ default:
+ LOG_INFO("JoinType(%d) not supported yet", type);
+ return univplan::UNIVPLANJOINTYPE::JOIN_NOT_SUPPORTED;
+ }
+}
+
+int32_t univPlanNestLoopNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_NESTLOOP);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+bool univPlanNestLoopSetType(UnivPlanC *up, UnivPlanCJoinType type) {
+ univplan::UNIVPLANJOINTYPE univplanType = joinTypeMapping(type);
+ if (univplanType == univplan::UNIVPLANJOINTYPE::JOIN_NOT_SUPPORTED)
+ return false;
+ dynamic_cast<univplan::UnivPlanBuilderNestLoop *>(up->curNode.get())
+ ->setJoinType(univplanType);
+ return true;
+}
+
+void univPlanNestLoopAddJoinQual(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderNestLoop *>(up->curNode.get())
+ ->addJoinQual(std::move(up->curExpr));
+}
+
+int32_t univPlanHashJoinNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_HASHJOIN);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+bool univPlanHashJoinSetType(UnivPlanC *up, UnivPlanCJoinType type) {
+ switch (type) {
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_INNER:
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_LEFT:
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_IN:
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_LASJ:
+ case UnivPlanCJoinType::UNIVPLAN_JOIN_LASJ_NOTIN:
+ break;
+ default:
+ return false;
+ }
+ dynamic_cast<univplan::UnivPlanBuilderHashJoin *>(up->curNode.get())
+ ->setJoinType(static_cast<univplan::UNIVPLANJOINTYPE>(type));
+ return true;
+}
+
+void univPlanHashJoinAddJoinQual(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderHashJoin *>(up->curNode.get())
+ ->addJoinQual(std::move(up->curExpr));
+}
+
+void univPlanHashJoinAddHashClause(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderHashJoin *>(up->curNode.get())
+ ->addHashClause(std::move(up->curExpr));
+}
+
+void univPlanHashJoinAddHashQualClause(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderHashJoin *>(up->curNode.get())
+ ->addHashQualClause(std::move(up->curExpr));
+}
+
+int32_t univPlanMergeJoinNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_MERGEJOIN);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+bool univPlanMergeJoinSetType(UnivPlanC *up, UnivPlanCJoinType type) {
+ univplan::UNIVPLANJOINTYPE univplanType = joinTypeMapping(type);
+ if (univplanType == univplan::UNIVPLANJOINTYPE::JOIN_NOT_SUPPORTED)
+ return false;
+ dynamic_cast<univplan::UnivPlanBuilderMergeJoin *>(up->curNode.get())
+ ->setJoinType(joinTypeMapping(type));
+ return true;
+}
+
+void univPlanMergeJoinAddJoinQual(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderMergeJoin *>(up->curNode.get())
+ ->addJoinQual(std::move(up->curExpr));
+}
+
+void univPlanMergeJoinAddMergeClause(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderMergeJoin *>(up->curNode.get())
+ ->addMergeClause(std::move(up->curExpr));
+}
+
+int32_t univPlanHashNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_HASH);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+static univplan::UNIVPLANSHARETYPE shareTypeMapping(UnivPlanCShareType type) {
+ switch (type) {
+ case UnivPlanCShareType::UNIVPLAN_SHARE_NOTSHARED:
+ return univplan::UNIVPLANSHARETYPE::SHARE_NOTSHARED;
+ case UnivPlanCShareType::UNIVPLAN_SHARE_MATERIAL_XSLICE:
+ return univplan::UNIVPLANSHARETYPE::SHARE_MATERIAL_XSLICE;
+ default:
+ LOG_INFO("ShareType(%d) not supported yet", type);
+ return univplan::UNIVPLANSHARETYPE::SHARE_NOT_SUPPORTED;
+ }
+}
+
+int32_t univPlanMaterialNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_MATERIAL);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+bool univPlanMaterialSetAttr(UnivPlanC *up, UnivPlanCShareType type,
+ bool cdbStrict, int32_t shareId,
+ int32_t driverSlice, int32_t nsharer,
+ int32_t xslice) {
+ univplan::UNIVPLANSHARETYPE univplanType = shareTypeMapping(type);
+ if (univplanType == univplan::UNIVPLANSHARETYPE::SHARE_NOT_SUPPORTED)
+ return false;
+ dynamic_cast<univplan::UnivPlanBuilderMaterial *>(up->curNode.get())
+ ->setShareType(univplanType)
+ .setCdbStrict(cdbStrict)
+ .setShareId(shareId)
+ .setDriverSlice(driverSlice)
+ .setNSharer(nsharer)
+ .setNSharerXSlice(xslice);
+ return true;
+}
+
+int32_t univPlanShareInputScanNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_SHAREINPUTSCAN);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+bool univPlanShareInputScanSetAttr(UnivPlanC *up, UnivPlanCShareType type,
+ int32_t shareId, int32_t driverSlice) {
+ univplan::UNIVPLANSHARETYPE univplanType = shareTypeMapping(type);
+ if (univplanType == univplan::UNIVPLANSHARETYPE::SHARE_NOT_SUPPORTED)
+ return false;
+ univplan::UnivPlanBuilderShareInputScan *bld =
+ dynamic_cast<univplan::UnivPlanBuilderShareInputScan *>(
+ up->curNode.get());
+ bld->setShareType(univplanType);
+ bld->setShareId(shareId);
+ bld->setDriverSlice(driverSlice);
+ return true;
+}
+
+int32_t univPlanResultNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_RESULT);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanResultAddResConstantQual(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderResult *>(up->curNode.get())
+ ->addResConstantQual(std::move(up->curExpr));
+}
+
+int32_t univPlanSubqueryScanNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode = univplan::PlanNodeUtil::createPlanBuilderNode(
+ univplan::UNIVPLAN_SUBQUERYSCAN);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+
+void univPlanSubqueryScanAddSubPlan(UnivPlanC *up) {
+ const univplan::UnivPlanPlanNodePoly &poly =
+ up->upb->getPlanBuilderPlan()->getPlan()->plan();
+ dynamic_cast<univplan::UnivPlanBuilderSubqueryScan *>(
+ up->curNodeBak.top().get())
+ ->setSubPlan(poly);
+}
+
+int32_t univPlanUniqueNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_UNIQUE);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ return up->curNode->uid;
+}
+void univPlanUniqueSetNumGroupsAndUniqColIdxs(UnivPlanC *up, int64_t numCols,
+ const int32_t *uniqColIdxs) {
+ auto uniq =
+ dynamic_cast<univplan::UnivPlanBuilderUnique *>(up->curNode.get());
+ uniq->setUniqColIdxs(numCols, uniqColIdxs);
+}
+
+int32_t univPlanInsertNewInstance(UnivPlanC *up, int32_t pid) {
+ up->curNode =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_INSERT);
+ up->curNode->pid = pid;
+ up->curNode->uid = up->upb->getUid();
+ up->totalStageNo += 1;
+ return up->curNode->uid;
+}
+
+void univPlanInsertSetRelId(UnivPlanC *up, uint32_t relId) {
+ dynamic_cast<univplan::UnivPlanBuilderInsert *>(up->curNode.get())
+ ->setInsertRelId(relId);
+}
+
+void univPlanAddToPlanNode(UnivPlanC *up, bool isLeft) {
+ up->upb->addPlanNode(isLeft, std::move(up->curNode));
+}
+
+UnivPlanCatchedError *univPlanGetLastError(UnivPlanC *up) {
+ return &(up->error);
+}
+
+void univPlanFixVarType(UnivPlanC *up) {
+ univplan::VarUtil varUtil;
+ varUtil.fixVarType(up->upb->getPlanBuilderPlan()->getPlan()->mutable_plan());
+}
+
+void univPlanStagize(UnivPlanC *up) {
+ univplan::PlanStagizer stagizer;
+ univplan::StagizerContext ctx;
+ ctx.totalStageNo = up->totalStageNo;
+ ctx.subplanStageNo = up->subplanStageNo;
+ stagizer.stagize(up->upb->getPlanBuilderPlan()->getPlan(), &ctx);
+ up->upb = std::move(ctx.upb);
+}
+
+void univPlanAddGuc(UnivPlanC *up, const char *name, const char *value) {
+ up->upb->getPlanBuilderPlan()->addGuc(name, value);
+}
+
+const char *univPlanSerialize(UnivPlanC *up, int32_t *size, bool compress) {
+ // compress
+ if (compress) {
+ std::string serializedPlan = up->upb->serialize();
+ dbcommon::LZ4Compressor comp;
+ comp.compress(serializedPlan.c_str(), serializedPlan.size(),
+ &up->serializedPlan);
+
+ } else {
+ up->serializedPlan = up->upb->serialize();
+ }
+ *size = up->serializedPlan.size();
+ return up->serializedPlan.data();
+}
+
+const char *univPlanGetJsonFormatedPlan(UnivPlanC *up) {
+ up->debugString = up->upb->getJsonFormatedPlan();
+ return up->debugString.c_str();
+}
+
+void univPlanSetError(UnivPlanCatchedError *ce, int errCode,
+ const char *errMsg) {
+ assert(ce != nullptr);
+ ce->errCode = errCode;
+ snprintf(ce->errMessage, strlen(errMsg) + 1, "%s", errMsg);
+}
+
+void univPlanNewExpr(UnivPlanC *up) {
+ up->curExpr.reset(new univplan::UnivPlanBuilderExprTree);
+}
+
+void univPlanQualListAddExpr(UnivPlanC *up) {
+ assert(up->curExpr);
+ up->curNode->addQualList(std::move(up->curExpr));
+}
+
+void univPlanInitplanAddExpr(UnivPlanC *up) {
+ assert(up->curExpr);
+ up->curNode->addInitplan(std::move(up->curExpr));
+}
+
+void univPlanTargetListAddTargetEntry(UnivPlanC *up, bool resJunk) {
+ assert(up->curExpr);
+ univplan::UnivPlanBuilderTargetEntry::uptr te =
+ up->curNode->addTargetEntryAndGetBuilder();
+ te->setResJunk(resJunk);
+ te->setExpr(std::move(up->curExpr));
+}
+
+void univPlanConnectorAddHashExpr(UnivPlanC *up) {
+ assert(up->curExpr);
+ // todo assert curNode is connector
+ dynamic_cast<univplan::UnivPlanBuilderConnector *>(up->curNode.get())
+ ->addHashExpr(std::move(up->curExpr));
+}
+
+void univPlanLimitAddLimitOffset(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderLimit *>(up->curNode.get())
+ ->setLimitOffset(std::move(up->curExpr));
+}
+
+void univPlanLimitAddLimitCount(UnivPlanC *up) {
+ assert(up->curExpr);
+ dynamic_cast<univplan::UnivPlanBuilderLimit *>(up->curNode.get())
+ ->setLimitCount(std::move(up->curExpr));
+}
+
+int32_t univPlanExprAddConst(UnivPlanC *up, int32_t pid, int32_t type,
+ bool isNull, const char *buffer, int64_t typeMod) {
+ assert(up->curExpr);
+ auto constVal =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderConst>(pid);
+ constVal->setType(type).setTypeMod(typeMod).setIsNull(isNull);
+ if (!isNull) constVal->setValue(buffer);
+
+ int32_t uid = constVal->uid;
+ up->curExpr->addExprNode(std::move(constVal));
+ return uid;
+}
+
+int32_t univPlanExprAddVar(UnivPlanC *up, int32_t pid, uint32_t varNo,
+ int32_t varAttNo, int32_t typeId, int64_t typeMod) {
+ assert(up->curExpr);
+ auto var = up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderVar>(pid);
+ var->setVarNo(varNo).setVarAttNo(varAttNo).setTypeId(typeId).setTypeMod(
+ typeMod);
+
+ int32_t uid = var->uid;
+ up->curExpr->addExprNode(std::move(var));
+ return uid;
+}
+
+int32_t univPlanExprAddOpExpr(UnivPlanC *up, int32_t pid, int32_t funcId) {
+ assert(up->curExpr);
+ auto opExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderOpExpr>(pid);
+ opExpr->setFuncId(funcId);
+ opExpr->setRetType(
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(funcId))
+ ->retType);
+
+ int32_t uid = opExpr->uid;
+ up->curExpr->addExprNode(std::move(opExpr));
+ return uid;
+}
+
+int32_t univPlanExprAddFuncExpr(UnivPlanC *up, int32_t pid, int32_t funcId) {
+ assert(up->curExpr);
+ auto funcExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderFuncExpr>(pid);
+ funcExpr->setFuncId(funcId);
+ funcExpr->setRetType(
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(funcId))
+ ->retType);
+
+ int32_t uid = funcExpr->uid;
+ up->curExpr->addExprNode(std::move(funcExpr));
+ return uid;
+}
+
+// Add type cast for final stage AGG function, in order to keep compatible with
+// HAWQ's optimizer and executor
+static int32_t univPlanAggrefAddFinalStageTypeCast(
+ UnivPlanC *up, int32_t pid, const dbcommon::AggEntry *aggEnt) {
+ if (aggEnt->aggFnId == dbcommon::FuncKind::AVG_SMALLINT ||
+ aggEnt->aggFnId == dbcommon::FuncKind::AVG_INT ||
+ aggEnt->aggFnId == dbcommon::FuncKind::AVG_BIGINT)
+ return univPlanExprAddFuncExpr(up, pid,
+ dbcommon::FuncKind::DOUBLE_TO_DECIMAL);
+ if (aggEnt->aggFnId == dbcommon::FuncKind::SUM_BIGINT)
+ return univPlanExprAddFuncExpr(up, pid,
+ dbcommon::FuncKind::BIGINT_TO_DECIMAL);
+ if (aggEnt->aggFnId == dbcommon::FuncKind::SUM_FLOAT)
+ return univPlanExprAddFuncExpr(up, pid,
+ dbcommon::FuncKind::DOUBLE_TO_FLOAT);
+ return pid;
+}
+
+int32_t univPlanAggrefAddPartialStage(UnivPlanC *up, int32_t pid,
+ int32_t funcId) {
+ assert(up->curExpr);
+ auto aggref =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderAggref>(pid);
+ const dbcommon::AggEntry *aggEntry =
+ dbcommon::Func::instance()->getAggEntryById(
+ static_cast<dbcommon::FuncKind>(funcId));
+ dbcommon::TypeKind retType = dbcommon::Func::instance()
+ ->getFuncEntryById(aggEntry->aggTransFnId)
+ ->retType;
+ aggref->setFuncId(funcId)
+ .setTransFuncId(aggEntry->aggTransFnId)
+ .setRetType(retType)
+ .setTransInitVal(aggEntry->aggInitVal);
+
+ int32_t uid = aggref->uid;
+ up->curExpr->addExprNode(std::move(aggref));
+ return uid;
+}
+
+int32_t univPlanAggrefAddIntermediateStage(UnivPlanC *up, int32_t pid,
+ int32_t funcId) {
+ assert(up->curExpr);
+ auto aggref =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderAggref>(pid);
+ const dbcommon::AggEntry *aggEntry =
+ dbcommon::Func::instance()->getAggEntryById(
+ static_cast<dbcommon::FuncKind>(funcId));
+ dbcommon::TypeKind retType = dbcommon::Func::instance()
+ ->getFuncEntryById(aggEntry->aggPrelimFnId)
+ ->retType;
+ aggref->setFuncId(funcId)
+ .setTransFuncId(aggEntry->aggPrelimFnId)
+ .setFinalFuncId(dbcommon::FuncKind::FUNCINVALID)
+ .setRetType(retType)
+ .setTransInitVal(aggEntry->aggInitVal);
+
+ int32_t uid = aggref->uid;
+ up->curExpr->addExprNode(std::move(aggref));
+ return uid;
+}
+
+int32_t univPlanAggrefAddFinalStage(UnivPlanC *up, int32_t pid,
+ int32_t funcId) {
+ assert(up->curExpr);
+ auto aggref =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderAggref>(pid);
+ const dbcommon::AggEntry *aggEntry =
+ dbcommon::Func::instance()->getAggEntryById(
+ static_cast<dbcommon::FuncKind>(funcId));
+ dbcommon::TypeKind retType =
+ dbcommon::Func::instance()
+ ->getFuncEntryById(aggEntry->aggFinalFn ==
+ dbcommon::FuncKind::FUNCINVALID
+ ? aggEntry->aggTransFnId
+ : aggEntry->aggFinalFn)
+ ->retType;
+ aggref->setFuncId(funcId)
+ .setTransFuncId(aggEntry->aggPrelimFnId)
+ .setFinalFuncId(aggEntry->aggFinalFn)
+ .setRetType(retType)
+ .setTransInitVal(aggEntry->aggInitVal);
+ if (aggEntry->aggFinalFn != dbcommon::FuncKind::FUNCINVALID)
+ aggref->setRetType(dbcommon::Func::instance()
+ ->getFuncEntryById(aggEntry->aggFinalFn)
+ ->retType);
+
+ int32_t uid = aggref->uid;
+ aggref->pid = univPlanAggrefAddFinalStageTypeCast(up, pid, aggEntry);
+ up->curExpr->addExprNode(std::move(aggref));
+ return uid;
+}
+
+int32_t univPlanAggrefAddOneStage(UnivPlanC *up, int32_t pid, int32_t funcId) {
+ assert(up->curExpr);
+ auto aggref =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderAggref>(pid);
+ const dbcommon::AggEntry *aggEntry =
+ dbcommon::Func::instance()->getAggEntryById(
+ static_cast<dbcommon::FuncKind>(funcId));
+ dbcommon::TypeKind retType =
+ dbcommon::Func::instance()
+ ->getFuncEntryById(aggEntry->aggFinalFn ==
+ dbcommon::FuncKind::FUNCINVALID
+ ? aggEntry->aggTransFnId
+ : aggEntry->aggFinalFn)
+ ->retType;
+ aggref->setFuncId(funcId)
+ .setTransFuncId(aggEntry->aggTransFnId)
+ .setFinalFuncId(aggEntry->aggFinalFn)
+ .setRetType(retType)
+ .setTransInitVal(aggEntry->aggInitVal);
+
+ int32_t uid = aggref->uid;
+ aggref->pid = univPlanAggrefAddFinalStageTypeCast(up, pid, aggEntry);
+ up->curExpr->addExprNode(std::move(aggref));
+ return uid;
+}
+
+int32_t univPlanAggrefAddProxyVar(UnivPlanC *up, int32_t pid, int32_t varAttNo,
+ int32_t funcId, int64_t typeMod) {
+ assert(up->curExpr);
+ auto var = up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderVar>(pid);
+ const dbcommon::AggEntry *aggEntry =
+ dbcommon::Func::instance()->getAggEntryById(
+ static_cast<dbcommon::FuncKind>(funcId));
+ dbcommon::TypeKind retType = dbcommon::Func::instance()
+ ->getFuncEntryById(aggEntry->aggTransFnId)
+ ->retType;
+ var->setVarNo(OUTER_VAR).setVarAttNo(varAttNo).setTypeId(retType).setTypeMod(
+ typeMod);
+
+ int32_t uid = var->uid;
+ up->curExpr->addExprNode(std::move(var));
+ return uid;
+}
+
+int32_t univPlanExprAddParam(UnivPlanC *up, int32_t pid,
+ UnivplanParamKind paramKind, int32_t paramId,
+ int32_t typeId, int64_t typeMod) {
+ assert(up->curExpr);
+ auto param =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderParam>(pid);
+ param->setParamKind(static_cast<univplan::PARAMKIND>(paramKind))
+ .setParamId(paramId)
+ .setTypeId(typeId)
+ .setTypeMod(typeMod);
+
+ int32_t uid = param->uid;
+ up->curExpr->addExprNode(std::move(param));
+ return uid;
+}
+
+int32_t univPlanExprAddSubPlan(UnivPlanC *up, int32_t pid,
+ UnivplanSubLinkType sublinkType, int32_t planId,
+ int32_t stageNo, int32_t typeId, int64_t typeMod,
+ bool useHashTable, bool initPlan) {
+ assert(up->curExpr);
+ auto subplan =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderSubPlan>(pid);
+ subplan->setSubLinkType(static_cast<univplan::SUBLINKTYPE>(sublinkType))
+ .setPlanId(planId)
+ .setTypeId(typeId)
+ .setTypeMod(typeMod)
+ .setUseHashTable(useHashTable)
+ .setInitPlan(initPlan);
+
+ int32_t uid = subplan->uid;
+ up->curExpr->addExprNode(std::move(subplan));
+ if (initPlan) up->subplanStageNo[planId] = stageNo;
+ return uid;
+}
+void univPlanExprAddSubPlanTestexpr(UnivPlanC *up, int32_t subplanId) {
+ reinterpret_cast<univplan::UnivPlanBuilderSubPlan *>(
+ up->curExpr->getExprNode(subplanId))
+ ->setAddingTestexpr();
+}
+
+void univPlanAddTokenEntry(UnivPlanC *up, FileSystemCredentialCPtr tokenEntry) {
+ std::string protocol(tokenEntry->key.protocol);
+ std::string host(tokenEntry->key.host);
+ int port = tokenEntry->key.port;
+ std::string token(tokenEntry->credential);
+ up->upb->getPlanBuilderPlan()->setTokenEntry(protocol, host, port, token);
+}
+
+void univPlanAddSnapshot(UnivPlanC *up, char *snapshot, int32_t snapshot_len) {
+ std::string Snapshot(snapshot, snapshot_len);
+ up->upb->getPlanBuilderPlan()->setSnapshot(Snapshot);
+ // LOG_DEBUG("univplan c add snapshot: %s, size: %d", Snapshot.c_str(),
+ // snapshot_len);
+}
+
+void univPlanSubPlanAddSetParam(UnivPlanC *up, int32_t subplanId, int32_t num,
+ int32_t *setParam) {
+ univplan::UnivPlanBuilderSubPlan *builder =
+ reinterpret_cast<univplan::UnivPlanBuilderSubPlan *>(
+ up->curExpr->getExprNode(subplanId));
+ for (int32_t i = 0; i < num; ++i) {
+ builder->addSetParam(setParam[i]);
+ }
+}
+
+void univPlanSubPlanAddParParam(UnivPlanC *up, int32_t subplanId, int32_t num,
+ int32_t *parParam) {
+ univplan::UnivPlanBuilderSubPlan *builder =
+ reinterpret_cast<univplan::UnivPlanBuilderSubPlan *>(
+ up->curExpr->getExprNode(subplanId));
+ for (int32_t i = 0; i < num; ++i) {
+ builder->addParParam(parParam[i]);
+ }
+}
+
+void univPlanSubPlanAddTestexprParam(UnivPlanC *up, int32_t subplanId,
+ int32_t num, int32_t *testexprParam) {
+ univplan::UnivPlanBuilderSubPlan *builder =
+ reinterpret_cast<univplan::UnivPlanBuilderSubPlan *>(
+ up->curExpr->getExprNode(subplanId));
+ for (int32_t i = 0; i < num; ++i) {
+ builder->addTestexprParam(testexprParam[i]);
+ }
+}
+
+int32_t univPlanExprAddBoolExpr(UnivPlanC *up, int32_t pid,
+ UnivplanBoolExprType boolExprType) {
+ assert(up->curExpr);
+ auto boolExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderBoolExpr>(pid);
+ boolExpr->setType(static_cast<univplan::BOOLEXPRTYPE>(boolExprType));
+
+ int32_t uid = boolExpr->uid;
+ up->curExpr->addExprNode(std::move(boolExpr));
+ return uid;
+}
+int32_t univPlanExprAddNullTestExpr(UnivPlanC *up, int32_t pid,
+ UnivplanNullTestType nullTestType) {
+ assert(up->curExpr);
+ auto nullTest =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderNullTest>(pid);
+ nullTest->setType(static_cast<univplan::NULLTESTTYPE>(nullTestType));
+
+ int32_t uid = nullTest->uid;
+ up->curExpr->addExprNode(std::move(nullTest));
+ return uid;
+}
+
+int32_t univPlanExprAddBoolTestExpr(UnivPlanC *up, int32_t pid,
+ UnivplanBooleanTestType boolTestType) {
+ assert(up->curExpr);
+ auto boolTest =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderBooleanTest>(pid);
+ boolTest->setType(static_cast<univplan::BOOLTESTTYPE>(boolTestType));
+
+ int32_t uid = boolTest->uid;
+ up->curExpr->addExprNode(std::move(boolTest));
+ return uid;
+}
+
+int32_t univPlanExprAddCaseExpr(UnivPlanC *up, int32_t pid, int32_t casetype) {
+ auto caseexpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderCaseExpr>(pid);
+ caseexpr->setCasetype(casetype);
+
+ int32_t uid = caseexpr->uid;
+ up->curExpr->addExprNode(std::move(caseexpr));
+ return uid;
+}
+
+void univPlanExprAddCaseExprDefresult(UnivPlanC *up, int32_t caseexpr_id) {
+ reinterpret_cast<univplan::UnivPlanBuilderCaseExpr *>(
+ up->curExpr->getExprNode(caseexpr_id))
+ ->setAddingDefresult();
+}
+
+int32_t univPlanExprAddCaseWhen(UnivPlanC *up, int32_t pid) {
+ auto casewhen =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderCaseWhen>(pid);
+
+ int32_t uid = casewhen->uid;
+ up->curExpr->addExprNode(std::move(casewhen));
+ return uid;
+}
+
+void univPlanExprAddCaseWhenExpr(UnivPlanC *up, int32_t casewhen_id) {}
+
+void univPlanExprAddCaseWhenResult(UnivPlanC *up, int32_t casewhen_id) {
+ reinterpret_cast<univplan::UnivPlanBuilderCaseWhen *>(
+ up->curExpr->getExprNode(casewhen_id))
+ ->setAddingResult();
+}
+
+int32_t univPlanExprAddScalarArrayOpExpr(UnivPlanC *up, int32_t pid,
+ int32_t funcId, bool useOr) {
+ assert(up->curExpr);
+ auto opExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderScalarArrayOpExpr>(
+ pid);
+ opExpr->setFuncId(funcId).setUseOr(useOr);
+
+ int32_t uid = opExpr->uid;
+ up->curExpr->addExprNode(std::move(opExpr));
+ return uid;
+}
+
+int32_t univPlanExprAddCoalesceExpr(UnivPlanC *up, int32_t pid,
+ int32_t coalesceType,
+ int32_t coalesceTypeMod) {
+ auto coalesceExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderCoalesceExpr>(pid);
+ coalesceExpr->setCoalesceType(coalesceType)
+ .setCoalesceTypeMod(coalesceTypeMod);
+ int32_t uid = coalesceExpr->uid;
+ up->curExpr->addExprNode(std::move(coalesceExpr));
+ return uid;
+}
+
+int32_t univPlanExprAddNullIfExpr(UnivPlanC *up, int32_t pid, int32_t funcId,
+ int32_t retType, int32_t typeMod) {
+ assert(up->curExpr);
+ auto nullIfExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderNullIfExpr>(pid);
+ nullIfExpr->setFuncId(funcId);
+ nullIfExpr->setRetType(retType);
+ nullIfExpr->setTypeMod(typeMod);
+
+ int32_t uid = nullIfExpr->uid;
+ up->curExpr->addExprNode(std::move(nullIfExpr));
+ return uid;
+}
+
+int32_t univPlanExprAddDistinctExpr(UnivPlanC *up, int32_t pid,
+ int32_t funcId) {
+ assert(up->curExpr);
+ auto distinctExpr =
+ up->curExpr->ExprNodeFactory<univplan::UnivPlanBuilderDistinctExpr>(pid);
+ distinctExpr->setFuncId(funcId);
+ distinctExpr->setRetType(
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(funcId))
+ ->retType);
+
+ int32_t uid = distinctExpr->uid;
+ up->curExpr->addExprNode(std::move(distinctExpr));
+ return uid;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/depends/univplan/src/univplan/cwrapper/univplan-c.h b/depends/univplan/src/univplan/cwrapper/univplan-c.h
new file mode 100644
index 0000000..ae7ddfe
--- /dev/null
+++ b/depends/univplan/src/univplan/cwrapper/univplan-c.h
@@ -0,0 +1,352 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_CWRAPPER_UNIVPLAN_C_H_
+#define UNIVPLAN_SRC_UNIVPLAN_CWRAPPER_UNIVPLAN_C_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef ERROR_MESSAGE_BUFFER_SIZE
+#define ERROR_MESSAGE_BUFFER_SIZE 4096
+#endif
+
+struct UnivPlanC;
+
+typedef struct UnivPlanC UnivPlanC;
+
+typedef struct FileSystemCredentialKeyC {
+ char *protocol;
+ char *host;
+ int port;
+} FileSystemCredentialKeyC;
+
+typedef struct FileSystemCredentialC {
+ struct FileSystemCredentialKeyC key;
+ char *credential;
+} FileSystemCredentialC;
+
+typedef struct FileSystemCredentialC *FileSystemCredentialCPtr;
+
+typedef struct UnivPlanCatchedError {
+ int errCode;
+ char errMessage[ERROR_MESSAGE_BUFFER_SIZE];
+} UnivPlanCatchedError;
+
+UnivPlanC *univPlanNewInstance();
+void univPlanFreeInstance(UnivPlanC **up);
+
+void univPlanNewSubPlanNode(UnivPlanC *up);
+void univPlanFreeSubPlanNode(UnivPlanC *up);
+
+// fill RangeTblEntry
+typedef enum FormatType {
+ UnivPlanTextFormat,
+ UnivPlanCsvFormat,
+ UnivPlanOrcFormat,
+ UnivPlanMagmaFormat
+} FormatType;
+void univPlanRangeTblEntryAddTable(UnivPlanC *up, uint64_t tid,
+ FormatType format, const char *location,
+ const char *optStrInJson, uint32_t columnNum,
+ const char **columnName,
+ int32_t *columnDataType,
+ int64_t *columnDataTypeMod);
+void univPlanRangeTblEntryAddDummy(UnivPlanC *up);
+
+// construct interconnect info
+void univPlanReceiverAddListeners(UnivPlanC *up, uint32_t listenerNum,
+ const char **addr, int32_t *port);
+
+// add param info
+void univPlanAddParamInfo(UnivPlanC *up, int32_t type, bool isNull,
+ const char *buffer);
+
+void univPlanSetDoInstrument(UnivPlanC *up, bool doInstrument);
+
+void univPlanSetNCrossLevelParams(UnivPlanC *up, int32_t nCrossLevelParams);
+
+typedef enum UnivPlanCCmdType {
+ UNIVPLAN_CMD_UNKNOWN,
+ UNIVPLAN_CMD_SELECT,
+ UNIVPLAN_CMD_UPDATE,
+ UNIVPLAN_CMD_INSERT,
+ UNIVPLAN_CMD_DELETE,
+ UNIVPLAN_CMD_UTILITY,
+ UNIVPLAN_CMD_NOTHING
+} UnivPlanCCmdType;
+void univPlanSetCmdType(UnivPlanC *up, UnivPlanCCmdType type);
+
+void univPlanSetPlanNodeInfo(UnivPlanC *up, double planRows,
+ int32_t planRowWidth, uint64_t operatorMemKB);
+
+/*
+ * the expr tree must be built before adding targetlist/qualist
+ */
+void univPlanQualListAddExpr(UnivPlanC *up);
+void univPlanInitplanAddExpr(UnivPlanC *up);
+void univPlanTargetListAddTargetEntry(UnivPlanC *up, bool resJunk);
+void univPlanConnectorAddHashExpr(UnivPlanC *up);
+void univPlanConnectorSetRangeVsegMap(UnivPlanC *up, int *map, bool magmaTable);
+// set magma range num
+void univPlanSetRangeNum(UnivPlanC *up, int rangeNum);
+
+// construct Connector
+typedef enum ConnectorType {
+ UnivPlanShuffle,
+ UnivPlanBroadcast,
+ UnivPlanConverge
+} ConnectorType;
+int32_t univPlanConnectorNewInstance(UnivPlanC *up, int32_t);
+void univPlanConnectorSetType(UnivPlanC *up, ConnectorType type);
+void univPlanConnectorSetStageNo(UnivPlanC *up, int32_t stageNo);
+void univPlanConnectorSetColIdx(UnivPlanC *up, int64_t numCols,
+ const int32_t *colIdx);
+void univPlanConnectorSetSortFuncId(UnivPlanC *up, int64_t numCols,
+ const int32_t *sortFuncId);
+
+// construct ExtScan
+int32_t univPlanExtScanNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanExtScanSetRelId(UnivPlanC *up, uint32_t relId);
+void univPlanExtScanSetColumnsToRead(UnivPlanC *up, int64_t numCols,
+ const int32_t *columnsToRead);
+// construct magma index info
+void univPlanExtScanSetIndex(UnivPlanC *up, bool index);
+void univPlanExtScanSetScanType(UnivPlanC *up, int type);
+void univPlanExtScanDirection(UnivPlanC *up, int direction);
+void univPlanExtScanSetIndexName(UnivPlanC *up, const char *indexName);
+void univPlanIndexQualListAddExpr(UnivPlanC *up);
+
+/*void univPlanExtScanAddTaskWithFileSplits(UnivPlanC *up, uint32_t
+ fileSplitNum, int64_t *lbLen, int64_t *ubLen, const char **lowerBound, const
+ char **upperBound);
+*/
+// construct SeqScan
+int32_t univPlanSeqScanNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanSeqScanSetRelId(UnivPlanC *up, uint32_t relId);
+void univPlanSeqScanSetReadStatsOnly(UnivPlanC *up, bool readStatsOnly);
+void univPlanSeqScanSetColumnsToRead(UnivPlanC *up, int64_t numCols,
+ const int32_t *columnsToRead);
+void univPlanSeqScanAddTaskWithFileSplits(bool isMagma, UnivPlanC *up,
+ uint32_t fileSplitNum,
+ const char **fileName, int64_t *start,
+ int64_t *len, int32_t *rangeid,
+ int32_t *rgid);
+
+// construct Agg
+int32_t univPlanAggNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanAggSetNumGroupsAndGroupColIndexes(UnivPlanC *up, int64_t numGroups,
+ int64_t numCols,
+ const int32_t *grpColIdx);
+
+// construct Sort
+int32_t univPlanSortNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanSortSetColIdx(UnivPlanC *up, int64_t numCols,
+ const int32_t *colIdx);
+void univPlanSortSetSortFuncId(UnivPlanC *up, int64_t numCols,
+ const int32_t *sortFuncId);
+void univPlanSortAddLimitOffset(UnivPlanC *up);
+void univPlanSortAddLimitCount(UnivPlanC *up);
+
+// construct Limit
+int32_t univPlanLimitNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanLimitAddLimitOffset(UnivPlanC *up);
+void univPlanLimitAddLimitCount(UnivPlanC *up);
+
+// construct append
+int32_t univPlanAppendNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanAppendAddAppendPlan(UnivPlanC *up);
+
+typedef enum UnivPlanCJoinType {
+ UNIVPLAN_JOIN_INNER,
+ UNIVPLAN_JOIN_LEFT,
+ UNIVPLAN_JOIN_RIGHT,
+ UNIVPLAN_JOIN_FULL,
+ UNIVPLAN_JOIN_IN,
+ UNIVPLAN_JOIN_LASJ = 8,
+ UNIVPLAN_JOIN_LASJ_NOTIN = 9
+} UnivPlanCJoinType;
+// construct nestloop
+int32_t univPlanNestLoopNewInstance(UnivPlanC *up, int32_t pid);
+bool univPlanNestLoopSetType(UnivPlanC *up, UnivPlanCJoinType type);
+void univPlanNestLoopAddJoinQual(UnivPlanC *up);
+// construct hashjoin
+int32_t univPlanHashJoinNewInstance(UnivPlanC *up, int32_t pid);
+bool univPlanHashJoinSetType(UnivPlanC *up, UnivPlanCJoinType type);
+void univPlanHashJoinAddJoinQual(UnivPlanC *up);
+void univPlanHashJoinAddHashClause(UnivPlanC *up);
+void univPlanHashJoinAddHashQualClause(UnivPlanC *up);
+// construct mergejoin
+int32_t univPlanMergeJoinNewInstance(UnivPlanC *up, int32_t pid);
+bool univPlanMergeJoinSetType(UnivPlanC *up, UnivPlanCJoinType type);
+void univPlanMergeJoinAddJoinQual(UnivPlanC *up);
+void univPlanMergeJoinAddMergeClause(UnivPlanC *up);
+
+// construct hash
+int32_t univPlanHashNewInstance(UnivPlanC *up, int32_t pid);
+
+typedef enum UnivPlanCShareType {
+ UNIVPLAN_SHARE_NOTSHARED,
+ UNIVPLAN_SHARE_MATERIAL,
+ UNIVPLAN_SHARE_MATERIAL_XSLICE,
+ UNIVPLAN_SHARE_SORT,
+ UNIVPLAN_SHARE_SORT_XSLICE
+} UnivPlanCShareType;
+// construct material
+int32_t univPlanMaterialNewInstance(UnivPlanC *up, int32_t pid);
+bool univPlanMaterialSetAttr(UnivPlanC *up, UnivPlanCShareType type,
+ bool cdbStrict, int32_t shareId,
+ int32_t driverSlice, int32_t nsharer,
+ int32_t xslice);
+
+// construct shareinputscan
+int32_t univPlanShareInputScanNewInstance(UnivPlanC *up, int32_t pid);
+bool univPlanShareInputScanSetAttr(UnivPlanC *up, UnivPlanCShareType type,
+ int32_t shareId, int32_t driverSlice);
+
+// construct result
+int32_t univPlanResultNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanResultAddResConstantQual(UnivPlanC *up);
+
+// construct subqueryscan
+int32_t univPlanSubqueryScanNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanSubqueryScanAddSubPlan(UnivPlanC *up);
+
+// construct Unique
+int32_t univPlanUniqueNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanUniqueSetNumGroupsAndUniqColIdxs(UnivPlanC *up, int64_t numCols,
+ const int32_t *uniqColIdxs);
+
+// construct Insert
+int32_t univPlanInsertNewInstance(UnivPlanC *up, int32_t pid);
+void univPlanInsertSetRelId(UnivPlanC *up, uint32_t relId);
+
+void univPlanAddToPlanNode(UnivPlanC *up, bool isLeft);
+
+void univPlanFixVarType(UnivPlanC *up);
+
+void univPlanStagize(UnivPlanC *up);
+
+void univPlanAddGuc(UnivPlanC *up, const char *name, const char *value);
+
+const char *univPlanSerialize(UnivPlanC *up, int32_t *size, bool compress);
+
+UnivPlanCatchedError *univPlanGetLastError(UnivPlanC *up);
+
+// call before add expr node
+void univPlanNewExpr(UnivPlanC *up);
+
+// following functions return the id of the new expr node in the expr tree
+// which will be used as the pid for adding its argument in the expr tree
+int32_t univPlanExprAddConst(UnivPlanC *up, int32_t pid, int32_t type,
+ bool isNull, const char *buffer, int64_t typeMod);
+int32_t univPlanExprAddVar(UnivPlanC *up, int32_t pid, uint32_t varNo,
+ int32_t varAttNo, int32_t typeId, int64_t typeMod);
+int32_t univPlanExprAddOpExpr(UnivPlanC *up, int32_t pid, int32_t funcId);
+int32_t univPlanExprAddFuncExpr(UnivPlanC *up, int32_t pid, int32_t funcId);
+int32_t univPlanAggrefAddPartialStage(UnivPlanC *up, int32_t pid,
+ int32_t funcId);
+int32_t univPlanAggrefAddIntermediateStage(UnivPlanC *up, int32_t pid,
+ int32_t funcId);
+int32_t univPlanAggrefAddFinalStage(UnivPlanC *up, int32_t pid, int32_t funcId);
+int32_t univPlanAggrefAddOneStage(UnivPlanC *up, int32_t pid, int32_t funcId);
+int32_t univPlanAggrefAddProxyVar(UnivPlanC *up, int32_t pid, int32_t varAttNo,
+ int32_t funcId, int64_t typeMod);
+typedef enum { UNIVPLAN_PARAM_EXTERN, UNIVPLAN_PARAM_EXEC } UnivplanParamKind;
+int32_t univPlanExprAddParam(UnivPlanC *up, int32_t pid,
+ UnivplanParamKind paramKind, int32_t paramId,
+ int32_t typeId, int64_t typeMod);
+typedef enum {
+ UNIVPLAN_EXISTS_SUBLINK = 0,
+ UNIVPLAN_ALL_SUBLINK = 1,
+ UNIVPLAN_ANY_SUBLINK = 2,
+ UNIVPLAN_ROWCOMPARE_SUBLINK = 3,
+ UNIVPLAN_EXPR_SUBLINK = 4,
+ UNIVPLAN_ARRAY_SUBLINK = 5,
+ UNIVPLAN_NOT_EXISTS_SUBLINK = 6
+} UnivplanSubLinkType;
+int32_t univPlanExprAddSubPlan(UnivPlanC *up, int32_t pid,
+ UnivplanSubLinkType sublinkType, int32_t planId,
+ int32_t stageNo, int32_t typeId, int64_t typeMod,
+ bool useHashTable, bool initPlan);
+void univPlanExprAddSubPlanTestexpr(UnivPlanC *up, int32_t subplanId);
+
+void univPlanAddTokenEntry(UnivPlanC *up, FileSystemCredentialCPtr tokenEntry);
+void univPlanAddSnapshot(UnivPlanC *up, char *snapshot, int32_t snapshot_len);
+void univPlanSubPlanAddSetParam(UnivPlanC *up, int32_t subplanId, int32_t num,
+ int32_t *setParam);
+void univPlanSubPlanAddParParam(UnivPlanC *up, int32_t subplanId, int32_t num,
+ int32_t *parParam);
+void univPlanSubPlanAddTestexprParam(UnivPlanC *up, int32_t subplanId,
+ int32_t num, int32_t *testexprParam);
+
+typedef enum {
+ UNIVPLAN_BOOLEXPRTYPE_AND_EXPR,
+ UNIVPLAN_BOOLEXPRTYPE_OR_EXPR,
+ UNIVPLAN_BOOLEXPRTYPE_NOT_EXPR
+} UnivplanBoolExprType;
+int32_t univPlanExprAddBoolExpr(UnivPlanC *up, int32_t pid,
+ UnivplanBoolExprType boolExprType);
+typedef enum {
+ UNIVPLAN_NULLTESTTYPE_IS_NULL,
+ UNIVPLAN_NULLTESTTYPE_IS_NOT_NULL
+} UnivplanNullTestType;
+int32_t univPlanExprAddNullTestExpr(UnivPlanC *up, int32_t pid,
+ UnivplanNullTestType nullTestType);
+
+typedef enum {
+ UNIVPLAN_BOOLEANTESTTYPE_IS_TRUE,
+ UNIVPLAN_BOOLEANTESTTYPE_IS_NOT_TRUE,
+ UNIVPLAN_BOOLEANTESTTYPE_IS_FALSE,
+ UNIVPLAN_BOOLEANTESTTYPE_IS_NOT_FALSE,
+ UNIVPLAN_BOOLEANTESTTYPE_IS_UNKNOWN,
+ UNIVPLAN_BOOLEANTESTTYPE_IS_NOT_UNKNOWN
+} UnivplanBooleanTestType;
+int32_t univPlanExprAddBoolTestExpr(UnivPlanC *up, int32_t pid,
+ UnivplanBooleanTestType boolTestType);
+
+int32_t univPlanExprAddCaseExpr(UnivPlanC *up, int32_t pid, int32_t casetype);
+void univPlanExprAddCaseExprDefresult(UnivPlanC *up, int32_t caseexpr_id);
+int32_t univPlanExprAddCaseWhen(UnivPlanC *up, int32_t pid);
+void univPlanExprAddCaseWhenExpr(UnivPlanC *up, int32_t casewhen_id);
+void univPlanExprAddCaseWhenResult(UnivPlanC *up, int32_t casewhen_id);
+
+int32_t univPlanExprAddScalarArrayOpExpr(UnivPlanC *up, int32_t pid,
+ int32_t funcId, bool useOr);
+
+int32_t univPlanExprAddCoalesceExpr(UnivPlanC *up, int32_t pid,
+ int32_t coalesceType,
+ int32_t coalesceTypeMod);
+
+int32_t univPlanExprAddNullIfExpr(UnivPlanC *up, int32_t pid, int32_t funcId,
+ int32_t retType, int32_t typeMod);
+
+int32_t univPlanExprAddDistinctExpr(UnivPlanC *up, int32_t pid, int32_t funcId);
+
+// debug
+const char *univPlanGetJsonFormatedPlan(UnivPlanC *up);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_CWRAPPER_UNIVPLAN_C_H_
diff --git a/depends/univplan/src/univplan/minmax/minmax-predicates.cc b/depends/univplan/src/univplan/minmax/minmax-predicates.cc
new file mode 100644
index 0000000..84bbc79
--- /dev/null
+++ b/depends/univplan/src/univplan/minmax/minmax-predicates.cc
@@ -0,0 +1,596 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/minmax/minmax-predicates.h"
+
+#include <memory>
+#include <sstream>
+#include <utility>
+
+#include "dbcommon/log/logger.h"
+#include "dbcommon/type/type-util.h"
+#include "dbcommon/utils/string-util.h"
+
+#include "univplan/common/plannode-walker.h"
+
+namespace univplan {
+
+ListPredicate::ListPredicate(const univplan::UnivPlanExprPolyList* exprs,
+ const MinMaxPredicatesAbstract* pred)
+ : PredicateOper(pred) {
+ for (int i = 0; i < exprs->size(); ++i) {
+ children.push_back(
+ MinMaxPredicatesAbstract::buildPredicateOper(&exprs->Get(i), pred));
+ }
+}
+
+bool ListPredicate::canDrop() {
+ // behave as And
+ for (PredicateOper::uptr& child : children) {
+ if (child->canDrop()) return true;
+ }
+ return false;
+}
+
+BooleanPredicate::BooleanPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBoolExpr* op)
+ : PredicateOper(pred) {
+ for (int i = 0; i < op->args_size(); ++i) {
+ children.push_back(
+ MinMaxPredicatesAbstract::buildPredicateOper(&op->args(i), pred));
+ }
+}
+
+bool VarPredicate::canDrop() {
+ if (PREDPAGE(pred)->hasAllNull(var->varattno())) return true;
+ PredicateStats s = PREDPAGE(pred)->getMinMax(var->varattno());
+ if (s.hasMinMax && !dbcommon::DatumGetValue<bool>(s.maxValue.value))
+ return true;
+ return false;
+}
+
+bool IsTrueBooleanTestPredicate::canDrop() {
+ if (PREDPAGE(pred)->hasAllNull(var->varattno())) return true;
+ PredicateStats s = PREDPAGE(pred)->getMinMax(var->varattno());
+ if (s.hasMinMax && !dbcommon::DatumGetValue<bool>(s.maxValue.value))
+ return true;
+ return false;
+}
+
+bool IsNotTrueBooleanTestPredicate::canDrop() {
+ if (!PREDPAGE(pred)->hasNull(var->varattno())) {
+ PredicateStats s = PREDPAGE(pred)->getMinMax(var->varattno());
+ if (s.hasMinMax && dbcommon::DatumGetValue<bool>(s.minValue.value))
+ return true;
+ }
+ return false;
+}
+
+bool IsFalseBooleanTestPredicate::canDrop() {
+ if (PREDPAGE(pred)->hasAllNull(var->varattno())) return true;
+ PredicateStats s = PREDPAGE(pred)->getMinMax(var->varattno());
+ if (s.hasMinMax && dbcommon::DatumGetValue<bool>(s.minValue.value))
+ return true;
+ return false;
+}
+
+bool IsNotFalseBooleanTestPredicate::canDrop() {
+ if (!PREDPAGE(pred)->hasNull(var->varattno())) {
+ PredicateStats s = PREDPAGE(pred)->getMinMax(var->varattno());
+ if (s.hasMinMax && !dbcommon::DatumGetValue<bool>(s.maxValue.value))
+ return true;
+ }
+ return false;
+}
+
+bool IsUnknownBooleanTestPredicate::canDrop() {
+ if (!PREDPAGE(pred)->hasNull(var->varattno())) return true;
+ return false;
+}
+
+bool IsNotUnknownBooleanTestPredicate::canDrop() {
+ if (PREDPAGE(pred)->hasAllNull(var->varattno())) return true;
+ return false;
+}
+
+bool AndPredicate::canDrop() {
+ // as long as one branch is OK to drop, we can drop it.
+ for (PredicateOper::uptr& child : children) {
+ if (child->canDrop()) return true;
+ }
+ return false;
+}
+
+bool OrPredicate::canDrop() {
+ // as long as one branch is NOT ok to drop, we can NOT drop it.
+ for (PredicateOper::uptr& child : children) {
+ if (!child->canDrop()) return false;
+ }
+ return true;
+}
+
+bool IsNullPredicate::canDrop() {
+ // as long as one var has null, we can't drop it
+ for (auto index : varAttrNo) {
+ if (PREDPAGE(pred)->hasNull(index)) return false;
+ }
+ return true;
+}
+
+bool IsNotNullPredicate::canDrop() {
+ // if one var has all null, we can drop it
+ for (auto index : varAttrNo) {
+ if (PREDPAGE(pred)->hasAllNull(index)) return true;
+ }
+ return false;
+}
+
+dbcommon::TupleBatch::uptr CompPredicate::buildTupleBatch(int32_t argIndex) {
+ dbcommon::TupleBatch::uptr batch(
+ new dbcommon::TupleBatch(*PREDPAGE(pred)->getTupleDesc(), true));
+ dbcommon::TupleBatchWriter& writer = batch->getTupleBatchWriter();
+ for (uint32_t i = 0; i < batch->getNumOfColumns(); ++i) {
+ if (varAttNo[argIndex].size() == 1 && i == varAttNo[argIndex][0] - 1) {
+ PredicateStats s =
+ PREDPAGE(pred)->getMinMax(i + 1, &minTimestamp, &maxTimestamp);
+ if (!s.hasMinMax) return nullptr;
+ writer[i]->append(&s.minValue);
+ writer[i]->append(&s.maxValue);
+ }
+ }
+ batch->incNumOfRows(2);
+ return std::move(batch);
+}
+
+PredicateStats::uptr CompPredicate::calcLeft() { return doCalc(0); }
+
+PredicateStats::uptr CompPredicate::calcRight() { return doCalc(1); }
+
+PredicateStats::uptr CompPredicate::doCalc(int32_t argIndex) {
+ PredicateStats::uptr stats(new PredicateStats);
+
+ if (varAttNo[argIndex].size() == 1 &&
+ PREDPAGE(pred)->hasAllNull(varAttNo[argIndex][0])) {
+ stats->hasAllNull = true;
+ return std::move(stats);
+ }
+
+ tbVec_.push_back(buildTupleBatch(argIndex));
+ if (!tbVec_[argIndex]) return nullptr;
+ ExprContext context;
+ context.scanBatch = tbVec_[argIndex].get();
+ dbcommon::Object* obj = dbcommon::DatumGetValue<dbcommon::Object*>(
+ args[argIndex]->calc(&context));
+ dbcommon::Vector* vec = dynamic_cast<dbcommon::Vector*>(obj);
+ if (!vec) {
+ dbcommon::Scalar* scalar = dynamic_cast<dbcommon::Scalar*>(obj);
+ stats->maxValue = *scalar;
+ stats->minValue = *scalar;
+ } else {
+ dbcommon::Scalar s1;
+ dbcommon::Scalar s2;
+ vec->readPlainScalar(0, &s1);
+ vec->readPlainScalar(1, &s2);
+ int32_t comRes =
+ compareTo(s1, typeKinds[argIndex], s2, typeKinds[argIndex]);
+ stats->maxValue = comRes >= 0 ? s1 : s2;
+ stats->minValue = comRes <= 0 ? s1 : s2;
+ }
+ return std::move(stats);
+}
+
+bool CompPredicate::isValidToPredicate() const {
+ // for arg1 op arg2, currently we only allow at most one variable
+ // exists in each side, and the two vars can't be the same one
+ if (varAttNo[0].size() > 1 || varAttNo[1].size() > 1) return false;
+
+ if (varAttNo[0].size() == 1 && varAttNo[1].size() == 1 &&
+ varAttNo[0][0] == varAttNo[1][0])
+ return false;
+
+ return true;
+}
+
+std::string CompPredicate::covertPredicateTypeStr(std::string typeName) {
+ if (typeName == "date")
+ return "int32";
+ else if (typeName == "time")
+ return "int64";
+ else if (typeName == "bpchar" || typeName == "varchar")
+ return "string";
+ return typeName;
+}
+
+int32_t CompPredicate::compareTo(const dbcommon::Scalar& s1,
+ dbcommon::TypeKind t1,
+ const dbcommon::Scalar& s2,
+ dbcommon::TypeKind t2) {
+ std::string type1 =
+ covertPredicateTypeStr(dbcommon::TypeUtil::getTypeNameById(t1));
+ std::string type2 =
+ covertPredicateTypeStr(dbcommon::TypeUtil::getTypeNameById(t2));
+ std::string funcName = type1 + "_less_than_" + type2;
+ const dbcommon::FuncEntry* funcEntry =
+ dbcommon::Func::instance()->getFuncEntryByName(funcName);
+ if (!funcEntry)
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "func name %s not found in func system",
+ funcName.c_str());
+ std::unique_ptr<dbcommon::Object> retval(new dbcommon::Scalar);
+ std::unique_ptr<dbcommon::Invoker> invoker(
+ new dbcommon::Invoker(funcEntry->funcId));
+ invoker->resetPrarmeter();
+ invoker->addParam(dbcommon::CreateDatum<dbcommon::Object*>(retval.get()));
+ invoker->addParam(dbcommon::CreateDatum<const dbcommon::Object*>(&s1));
+ invoker->addParam(dbcommon::CreateDatum<const dbcommon::Object*>(&s2));
+ invoker->invoke();
+ if (dbcommon::DatumGetValue<bool>(
+ dynamic_cast<dbcommon::Scalar*>(retval.get())->value))
+ return -1;
+
+ funcName = type1 + "_equal_" + type2;
+ funcEntry = dbcommon::Func::instance()->getFuncEntryByName(funcName);
+ if (!funcEntry)
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "func name %s not found in func system",
+ funcName.c_str());
+ invoker.reset(new dbcommon::Invoker(funcEntry->funcId));
+ invoker->resetPrarmeter();
+ invoker->addParam(dbcommon::CreateDatum<dbcommon::Object*>(retval.get()));
+ invoker->addParam(dbcommon::CreateDatum<const dbcommon::Object*>(&s1));
+ invoker->addParam(dbcommon::CreateDatum<const dbcommon::Object*>(&s2));
+ invoker->invoke();
+ if (dbcommon::DatumGetValue<bool>(
+ dynamic_cast<dbcommon::Scalar*>(retval.get())->value))
+ return 0;
+
+ return 1;
+}
+
+bool EqualPredicate::canDrop() {
+ if (!isValidToPredicate()) return false;
+
+ PredicateStats::uptr leftStat = this->calcLeft();
+ PredicateStats::uptr rightStat = this->calcRight();
+
+ // left or right has no statistics
+ if (leftStat == nullptr || rightStat == nullptr) return false;
+
+ // if either side is ALL null, can drop
+ if (leftStat->hasAllNull || rightStat->hasAllNull) return true;
+
+ // can drop when left's max < right's min, or right's max < left's min
+ if (compareTo(leftStat->maxValue, typeKinds[0], rightStat->minValue,
+ typeKinds[1]) < 0 ||
+ compareTo(rightStat->maxValue, typeKinds[1], leftStat->minValue,
+ typeKinds[0]) < 0)
+ return true;
+
+ // now check bloom filter
+ int32_t columnId;
+ PredicateStats* stat;
+ dbcommon::TypeKind type;
+ if (expr->args(0).has_var() && expr->args(1).has_val()) {
+ columnId = expr->args(0).var().varattno();
+ stat = rightStat.get();
+ type = typeKinds[1];
+ } else if (expr->args(1).has_var() && expr->args(0).has_val()) {
+ columnId = expr->args(1).var().varattno();
+ stat = leftStat.get();
+ type = typeKinds[0];
+ } else {
+ return false;
+ }
+
+ if (PREDPAGE(pred)->canDropByBloomFilter(columnId, stat, type)) return true;
+
+ return false;
+}
+
+bool NEPredicate::canDrop() {
+ if (!isValidToPredicate()) return false;
+
+ PredicateStats::uptr leftStat = this->calcLeft();
+ PredicateStats::uptr rightStat = this->calcRight();
+
+ // left or right has no statistics
+ if (leftStat == nullptr || rightStat == nullptr) return false;
+
+ // if either side is ALL null, can drop
+ if (leftStat->hasAllNull || rightStat->hasAllNull) return true;
+
+ // can drop when there is only one unique value.
+ if (compareTo(leftStat->minValue, typeKinds[0], leftStat->maxValue,
+ typeKinds[0]) == 0 &&
+ compareTo(rightStat->minValue, typeKinds[1], rightStat->maxValue,
+ typeKinds[1]) == 0 &&
+ compareTo(leftStat->maxValue, typeKinds[0], rightStat->maxValue,
+ typeKinds[1]) == 0)
+ return true;
+ else
+ return false;
+}
+
+bool GTPredicate::canDrop() {
+ if (!isValidToPredicate()) return false;
+
+ PredicateStats::uptr leftStat = this->calcLeft();
+ PredicateStats::uptr rightStat = this->calcRight();
+
+ // left or right has no statistics
+ if (leftStat == nullptr || rightStat == nullptr) return false;
+
+ // if either side is ALL null, can drop
+ if (leftStat->hasAllNull || rightStat->hasAllNull) return true;
+
+ // can drop when left's max <= right's min.
+ if (compareTo(leftStat->maxValue, typeKinds[0], rightStat->minValue,
+ typeKinds[1]) <= 0)
+ return true;
+ else
+ return false;
+}
+
+bool GEPredicate::canDrop() {
+ if (!isValidToPredicate()) return false;
+
+ PredicateStats::uptr leftStat = this->calcLeft();
+ PredicateStats::uptr rightStat = this->calcRight();
+
+ // left or right has no statistics
+ if (leftStat == nullptr || rightStat == nullptr) return false;
+
+ // if either side is ALL null, can drop
+ if (leftStat->hasAllNull || rightStat->hasAllNull) return true;
+
+ // can drop when left's max < right's min.
+ if (compareTo(leftStat->maxValue, typeKinds[0], rightStat->minValue,
+ typeKinds[1]) < 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool LTPredicate::canDrop() {
+ if (!isValidToPredicate()) return false;
+
+ PredicateStats::uptr leftStat = this->calcLeft();
+ PredicateStats::uptr rightStat = this->calcRight();
+
+ // left or right has no statistics
+ if (leftStat == nullptr || rightStat == nullptr) return false;
+
+ // if either side is ALL null, can drop
+ if (leftStat->hasAllNull || rightStat->hasAllNull) return true;
+
+ // can drop when right's max <= left's min.
+ if (compareTo(rightStat->maxValue, typeKinds[1], leftStat->minValue,
+ typeKinds[0]) <= 0)
+ return true;
+ else
+ return false;
+}
+
+bool LEPredicate::canDrop() {
+ if (!isValidToPredicate()) return false;
+
+ PredicateStats::uptr leftStat = this->calcLeft();
+ PredicateStats::uptr rightStat = this->calcRight();
+
+ // left or right has no statistics
+ if (leftStat == nullptr || rightStat == nullptr) return false;
+
+ // if either side is ALL null, can drop
+ if (leftStat->hasAllNull || rightStat->hasAllNull) return true;
+
+ // can drop when right's max < left's min.
+ if (compareTo(rightStat->maxValue, typeKinds[1], leftStat->minValue,
+ typeKinds[0]) < 0)
+ return true;
+ else
+ return false;
+}
+
+PredicateOper::uptr MinMaxPredicatesAbstract::buildPredicateOper(
+ const univplan::UnivPlanExprPolyList* exprs,
+ const MinMaxPredicatesAbstract* owner) {
+ return PredicateOper::uptr(new ListPredicate(exprs, owner));
+}
+
+PredicateOper::uptr MinMaxPredicatesAbstract::buildPredicateOper(
+ const univplan::UnivPlanExprPoly* expr,
+ const MinMaxPredicatesAbstract* owner) {
+ switch (expr->type()) {
+ case univplan::UNIVPLAN_EXPR_OPEXPR: {
+ const univplan::UnivPlanOpExpr& op = expr->opexpr();
+ CompPredicate::uptr ret;
+ std::string funcName =
+ dbcommon::Func::instance()
+ ->getFuncEntryById(static_cast<dbcommon::FuncKind>(op.funcid()))
+ ->funcName;
+ if (dbcommon::StringUtil::countReplicates(funcName, "less_than") == 1)
+ ret.reset(new LTPredicate(owner, &op));
+ else if (dbcommon::StringUtil::countReplicates(funcName, "less_eq") == 1)
+ ret.reset(new LEPredicate(owner, &op));
+ else if (dbcommon::StringUtil::countReplicates(funcName, "not_equal") ==
+ 1)
+ ret.reset(new NEPredicate(owner, &op));
+ else if (dbcommon::StringUtil::countReplicates(funcName, "equal") == 1)
+ ret.reset(new EqualPredicate(owner, &op));
+ else if (dbcommon::StringUtil::countReplicates(funcName,
+ "greater_than") == 1)
+ ret.reset(new GTPredicate(owner, &op));
+ else if (dbcommon::StringUtil::countReplicates(funcName, "greater_eq") ==
+ 1)
+ ret.reset(new GEPredicate(owner, &op));
+ else
+ goto end;
+ for (int i = 0; i < op.args_size(); ++i)
+ ret->addArg(InitExpr(&op.args(i)));
+ return std::move(ret);
+ }
+ case univplan::UNIVPLAN_EXPR_BOOLEXPR: {
+ const univplan::UnivPlanBoolExpr& op = expr->boolexpr();
+ BooleanPredicate::uptr ret;
+ if (op.type() == univplan::BOOLEXPRTYPE::BOOLEXPRTYPE_AND_EXPR)
+ ret.reset(new AndPredicate(owner, &op));
+ else if (op.type() == univplan::BOOLEXPRTYPE::BOOLEXPRTYPE_OR_EXPR)
+ ret.reset(new OrPredicate(owner, &op));
+ else
+ goto end;
+ return std::move(ret);
+ }
+ case univplan::UNIVPLAN_EXPR_NULLTEST: {
+ const univplan::UnivPlanNullTest& op = expr->nulltest();
+ NullTestPredicate::uptr ret;
+ if (op.type() == univplan::NULLTESTTYPE::NULLTESTTYPE_IS_NULL) {
+ ret.reset(new IsNullPredicate(owner, &op));
+ } else {
+ assert(op.type() == univplan::NULLTESTTYPE::NULLTESTTYPE_IS_NOT_NULL);
+ ret.reset(new IsNotNullPredicate(owner, &op));
+ }
+ return std::move(ret);
+ }
+ case univplan::UNIVPLAN_EXPR_VAR: {
+ const univplan::UnivPlanVar& var = expr->var();
+ VarPredicate::uptr ret(new VarPredicate(owner, &var));
+ return std::move(ret);
+ }
+ case univplan::UNIVPLAN_EXPR_BOOLEANTEST: {
+ const univplan::UnivPlanBooleanTest& op = expr->booltest();
+ BooleanTestPredicate::uptr ret;
+ if (op.type() == univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_TRUE) {
+ ret.reset(new IsTrueBooleanTestPredicate(owner, &op));
+ } else if (op.type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_NOT_TRUE) {
+ ret.reset(new IsNotTrueBooleanTestPredicate(owner, &op));
+ } else if (op.type() == univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_FALSE) {
+ ret.reset(new IsFalseBooleanTestPredicate(owner, &op));
+ } else if (op.type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_NOT_FALSE) {
+ ret.reset(new IsNotFalseBooleanTestPredicate(owner, &op));
+ } else if (op.type() == univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_UNKNOWN) {
+ ret.reset(new IsUnknownBooleanTestPredicate(owner, &op));
+ } else {
+ assert(op.type() ==
+ univplan::BOOLTESTTYPE::BOOLTESTTYPE_IS_NOT_UNKNOWN);
+ ret.reset(new IsNotUnknownBooleanTestPredicate(owner, &op));
+ }
+ return std::move(ret);
+ }
+ default: {
+ // do nothing
+ break;
+ }
+ }
+end:
+ LOG_INFO("Predicate warning: expr is not predicated: %s",
+ expr->DebugString().c_str());
+ PredicateOper::uptr ret(new PredicateOper(owner));
+ return std::move(ret);
+}
+
+bool MinMaxPredicatesPage::canDrop() {
+ if (nullptr == exprs) {
+ return false;
+ }
+
+ try {
+ predicate = MinMaxPredicatesAbstract::buildPredicateOper(exprs, this);
+ return predicate->canDrop();
+ } catch (...) {
+ return false;
+ }
+}
+
+COBlockTaskList::COBlockTaskList() {}
+
+void COBlockTaskList::intersect(const COBlockTaskList& source) {
+ auto selfIter = taskList.begin();
+ auto srcIter = source.taskList.begin();
+ if (selfIter != taskList.end()) {
+ selfIter->second->resetIntersection();
+ return; // no task to process
+ }
+ while (srcIter != source.taskList.end() && selfIter != taskList.end()) {
+ COBlockTask* selfTask = selfIter->second.get();
+ COBlockTask* srcTask = srcIter->second.get();
+ if (selfTask->taskBeginRowId > srcTask->getTaskEndRowId()) {
+ srcIter++; // try next source task
+ } else if (srcTask->taskBeginRowId > selfTask->getTaskEndRowId()) {
+ selfIter++;
+ if (selfIter != taskList.end()) {
+ selfIter->second->resetIntersection();
+ }
+ } else {
+ selfIter->second->intersect(*srcTask);
+ srcIter++; // try next source task
+ }
+ }
+}
+
+void COBlockTaskList::unionAll(const COBlockTaskList& source) {
+ auto selfIter = taskList.begin();
+ auto srcIter = source.taskList.begin();
+ if (selfIter != taskList.end()) {
+ selfIter->second->resetUnionAll();
+ return; // no task to process
+ }
+ while (srcIter != source.taskList.end() && selfIter != taskList.end()) {
+ COBlockTask* selfTask = selfIter->second.get();
+ COBlockTask* srcTask = srcIter->second.get();
+ if (selfTask->beginRowId > srcTask->getTaskEndRowId()) {
+ srcIter++; // try next source task
+ } else if (srcTask->taskBeginRowId > selfTask->getEndRowId()) {
+ selfIter++;
+ if (selfIter != taskList.end()) {
+ selfIter->second->resetUnionAll();
+ }
+ } else {
+ selfIter->second->unionAll(*srcTask);
+ srcIter++; // try next source task
+ }
+ }
+}
+
+void MinMaxPredicatesCO::preparePredicates() {
+ predicate.reset(new ListPredicate(exprs, this));
+}
+
+void MinMaxPredicatesCO::calculate(
+ std::unordered_map<int, COBlockTaskList::uptr>* res) {
+ // prepare res
+ for (int i = 0; i < this->td->getNumOfColumns(); ++i) {
+ (*res)[i + 1].reset(new COBlockTaskList());
+ }
+
+ while (true) {
+ predicatesForPages.reset();
+ preparePredicatesForStrip();
+ if (predicatesForPages == nullptr) {
+ break; // no more to work with
+ }
+ if (!predicatesForPages->canDrop()) {
+ for (auto iter = res->begin(); iter != res->end(); ++iter) {
+ iter->second->add(std::move(buildCOTaskFromCurrentStrip(iter->first)));
+ }
+ }
+ }
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/minmax/minmax-predicates.h b/depends/univplan/src/univplan/minmax/minmax-predicates.h
new file mode 100644
index 0000000..976b9c6
--- /dev/null
+++ b/depends/univplan/src/univplan/minmax/minmax-predicates.h
@@ -0,0 +1,604 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_MINMAX_MINMAX_PREDICATES_H_
+#define UNIVPLAN_SRC_UNIVPLAN_MINMAX_MINMAX_PREDICATES_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "dbcommon/common/tuple-batch.h"
+#include "dbcommon/common/tuple-desc.h"
+#include "dbcommon/nodes/datum.h"
+
+#include "univplan/common/expression.h"
+#include "univplan/common/statistics.h"
+#include "univplan/common/univplan-type.h"
+#include "univplan/common/var-util.h"
+
+namespace univplan {
+
+class PredicateStats {
+ public:
+ PredicateStats() {}
+ virtual ~PredicateStats() {}
+ typedef std::unique_ptr<PredicateStats> uptr;
+
+ dbcommon::Scalar maxValue;
+ dbcommon::Scalar minValue;
+ bool hasAllNull = false;
+ bool hasMinMax = false;
+};
+
+class MinMaxPredicatesAbstract;
+class MinMaxPredicatesPage;
+class MinMaxPredicatesCO;
+
+#define PREDPAGE(pred) (dynamic_cast<const MinMaxPredicatesPage*>(pred))
+#define PREDCO(pred) (dynamic_cast<const MinMaxPredicatesCO*>(pred))
+
+class PredicateOper {
+ public:
+ explicit PredicateOper(const MinMaxPredicatesAbstract* pred) : pred(pred) {}
+ virtual ~PredicateOper() {}
+
+ typedef std::unique_ptr<PredicateOper> uptr;
+
+ virtual bool canDrop() { return false; }
+
+ protected:
+ const MinMaxPredicatesAbstract* pred = nullptr;
+};
+
+class ListPredicate : public PredicateOper {
+ public:
+ ListPredicate(const univplan::UnivPlanExprPolyList* exprs,
+ const MinMaxPredicatesAbstract* pred);
+ ~ListPredicate() {}
+
+ typedef std::unique_ptr<ListPredicate> uptr;
+
+ bool canDrop() override;
+
+ private:
+ std::vector<PredicateOper::uptr> children;
+};
+
+class BooleanPredicate : public PredicateOper {
+ public:
+ BooleanPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBoolExpr* op);
+ ~BooleanPredicate() {}
+
+ typedef std::unique_ptr<BooleanPredicate> uptr;
+
+ protected:
+ std::vector<PredicateOper::uptr> children;
+};
+
+class VarPredicate : public PredicateOper {
+ public:
+ VarPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanVar* var)
+ : PredicateOper(pred), var(var) {}
+ ~VarPredicate() {}
+
+ typedef std::unique_ptr<VarPredicate> uptr;
+
+ bool canDrop() override;
+
+ private:
+ const univplan::UnivPlanVar* var;
+};
+
+class BooleanTestPredicate : public PredicateOper {
+ public:
+ BooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : PredicateOper(pred), var(&op->arg().var()) {}
+ ~BooleanTestPredicate() {}
+
+ typedef std::unique_ptr<BooleanTestPredicate> uptr;
+
+ protected:
+ const univplan::UnivPlanVar* var;
+};
+
+class IsTrueBooleanTestPredicate : public BooleanTestPredicate {
+ public:
+ IsTrueBooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : BooleanTestPredicate(pred, op) {}
+ ~IsTrueBooleanTestPredicate() {}
+
+ typedef std::unique_ptr<IsTrueBooleanTestPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class IsNotTrueBooleanTestPredicate : public BooleanTestPredicate {
+ public:
+ IsNotTrueBooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : BooleanTestPredicate(pred, op) {}
+ ~IsNotTrueBooleanTestPredicate() {}
+
+ typedef std::unique_ptr<IsNotTrueBooleanTestPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class IsFalseBooleanTestPredicate : public BooleanTestPredicate {
+ public:
+ IsFalseBooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : BooleanTestPredicate(pred, op) {}
+ ~IsFalseBooleanTestPredicate() {}
+
+ typedef std::unique_ptr<IsFalseBooleanTestPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class IsNotFalseBooleanTestPredicate : public BooleanTestPredicate {
+ public:
+ IsNotFalseBooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : BooleanTestPredicate(pred, op) {}
+ ~IsNotFalseBooleanTestPredicate() {}
+
+ typedef std::unique_ptr<IsNotFalseBooleanTestPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class IsUnknownBooleanTestPredicate : public BooleanTestPredicate {
+ public:
+ IsUnknownBooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : BooleanTestPredicate(pred, op) {}
+ ~IsUnknownBooleanTestPredicate() {}
+
+ typedef std::unique_ptr<IsUnknownBooleanTestPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class IsNotUnknownBooleanTestPredicate : public BooleanTestPredicate {
+ public:
+ IsNotUnknownBooleanTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBooleanTest* op)
+ : BooleanTestPredicate(pred, op) {}
+ ~IsNotUnknownBooleanTestPredicate() {}
+
+ typedef std::unique_ptr<IsNotUnknownBooleanTestPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class AndPredicate : public BooleanPredicate {
+ public:
+ AndPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBoolExpr* op)
+ : BooleanPredicate(pred, op) {}
+ ~AndPredicate() {}
+
+ typedef std::unique_ptr<AndPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class OrPredicate : public BooleanPredicate {
+ public:
+ OrPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanBoolExpr* op)
+ : BooleanPredicate(pred, op) {}
+ ~OrPredicate() {}
+
+ typedef std::unique_ptr<OrPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class NullTestPredicate : public PredicateOper {
+ public:
+ NullTestPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanNullTest* op)
+ : PredicateOper(pred) {
+ if (!op->arg().has_var())
+ LOG_ERROR(ERRCODE_FEATURE_NOT_SUPPORTED,
+ "NullTestPredicate only work for simple expression");
+ univplan::VarUtil varUtil;
+ varAttrNo = varUtil.collectVarAttNo(
+ const_cast<univplan::UnivPlanExprPoly*>(&op->arg()));
+ }
+ ~NullTestPredicate() {}
+
+ typedef std::unique_ptr<NullTestPredicate> uptr;
+
+ protected:
+ std::vector<int32_t> varAttrNo;
+};
+
+class IsNullPredicate : public NullTestPredicate {
+ public:
+ IsNullPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanNullTest* op)
+ : NullTestPredicate(pred, op) {}
+ ~IsNullPredicate() {}
+
+ typedef std::unique_ptr<IsNullPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class IsNotNullPredicate : public NullTestPredicate {
+ public:
+ IsNotNullPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanNullTest* op)
+ : NullTestPredicate(pred, op) {}
+ ~IsNotNullPredicate() {}
+
+ typedef std::unique_ptr<IsNotNullPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class CompPredicate : public PredicateOper {
+ public:
+ CompPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : PredicateOper(pred), expr(op) {
+ assert(op->args_size() == 2);
+ typeKinds.push_back(univplan::PlanNodeUtil::exprType(op->args(0)));
+ typeKinds.push_back(univplan::PlanNodeUtil::exprType(op->args(1)));
+ univplan::VarUtil varUtil;
+ varAttNo.push_back(varUtil.collectVarAttNo(
+ const_cast<univplan::UnivPlanExprPoly*>(&op->args(0))));
+ varAttNo.push_back(varUtil.collectVarAttNo(
+ const_cast<univplan::UnivPlanExprPoly*>(&op->args(1))));
+ }
+ ~CompPredicate() {}
+
+ typedef std::unique_ptr<CompPredicate> uptr;
+
+ void addArg(ExprState::uptr arg) { args.push_back(std::move(arg)); }
+
+ bool isValidToPredicate() const;
+
+ protected:
+ PredicateStats::uptr calcLeft();
+ PredicateStats::uptr calcRight();
+ int32_t compareTo(const dbcommon::Scalar& s1, dbcommon::TypeKind t1,
+ const dbcommon::Scalar& s2, dbcommon::TypeKind t2);
+
+ private:
+ dbcommon::TupleBatch::uptr buildTupleBatch(int32_t argIndex);
+ PredicateStats::uptr doCalc(int32_t argIndex);
+ std::string covertPredicateTypeStr(std::string typeName);
+
+ protected:
+ std::vector<dbcommon::TypeKind> typeKinds;
+ const univplan::UnivPlanOpExpr* expr;
+
+ private:
+ std::vector<ExprState::uptr> args;
+ std::vector<std::vector<int32_t>> varAttNo;
+ dbcommon::Timestamp minTimestamp;
+ dbcommon::Timestamp maxTimestamp;
+ std::vector<dbcommon::TupleBatch::uptr> tbVec_;
+};
+
+class EqualPredicate : public CompPredicate {
+ public:
+ EqualPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : CompPredicate(pred, op) {}
+ ~EqualPredicate() {}
+
+ typedef std::unique_ptr<EqualPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class NEPredicate : public CompPredicate {
+ public:
+ NEPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : CompPredicate(pred, op) {}
+ ~NEPredicate() {}
+
+ typedef std::unique_ptr<NEPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class GTPredicate : public CompPredicate {
+ public:
+ GTPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : CompPredicate(pred, op) {}
+ ~GTPredicate() {}
+
+ typedef std::unique_ptr<GTPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class GEPredicate : public CompPredicate {
+ public:
+ GEPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : CompPredicate(pred, op) {}
+ ~GEPredicate() {}
+
+ typedef std::unique_ptr<GEPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class LTPredicate : public CompPredicate {
+ public:
+ LTPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : CompPredicate(pred, op) {}
+ ~LTPredicate() {}
+
+ typedef std::unique_ptr<LTPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class LEPredicate : public CompPredicate {
+ public:
+ LEPredicate(const MinMaxPredicatesAbstract* pred,
+ const univplan::UnivPlanOpExpr* op)
+ : CompPredicate(pred, op) {}
+ ~LEPredicate() {}
+
+ typedef std::unique_ptr<LEPredicate> uptr;
+
+ bool canDrop() override;
+};
+
+class MinMaxPredicatesAbstract {
+ public:
+ MinMaxPredicatesAbstract(const univplan::UnivPlanExprPolyList* predicateExprs,
+ const dbcommon::TupleDesc* tupleDesc)
+ : exprs(predicateExprs), td(tupleDesc) {}
+ virtual ~MinMaxPredicatesAbstract() {}
+
+ // facility for building general purpose predicate tree
+ static PredicateOper::uptr buildPredicateOper(
+ const univplan::UnivPlanExprPolyList* exprs,
+ const MinMaxPredicatesAbstract* owner);
+
+ static PredicateOper::uptr buildPredicateOper(
+ const univplan::UnivPlanExprPoly* expr,
+ const MinMaxPredicatesAbstract* owner);
+
+ const dbcommon::TupleDesc* getTupleDesc() const { return td; }
+
+ protected:
+ const univplan::UnivPlanExprPolyList* exprs; // original pushed filter
+ const dbcommon::TupleDesc* td; // full tuple desc
+ PredicateOper::uptr predicate; // generated predicate
+};
+
+class MinMaxPredicatesPage : public MinMaxPredicatesAbstract {
+ public:
+ MinMaxPredicatesPage(const Statistics* s,
+ const univplan::UnivPlanExprPolyList* predicateExprs,
+ const dbcommon::TupleDesc* tupleDesc)
+ : MinMaxPredicatesAbstract(predicateExprs, tupleDesc), stripeStats(s) {}
+ virtual ~MinMaxPredicatesPage() {}
+
+ typedef std::unique_ptr<MinMaxPredicatesPage> uptr;
+
+ virtual bool canDrop(); // page level min-max calculation interface
+
+ public:
+ virtual bool hasNull(int32_t colId) const = 0;
+ virtual bool hasAllNull(int32_t colId) const = 0;
+ virtual bool canDropByBloomFilter(int32_t colId, PredicateStats* stat,
+ dbcommon::TypeKind type) const = 0;
+ virtual PredicateStats getMinMax(int32_t colId) const = 0;
+ virtual PredicateStats getMinMax(int32_t colId,
+ dbcommon::Timestamp* minTimestamp,
+ dbcommon::Timestamp* maxTimestamp) const = 0;
+
+ protected:
+ const Statistics* stripeStats;
+};
+
+class COBlockTask {
+ public:
+ COBlockTask(uint64_t offset, uint64_t beginRowId, uint64_t rowCount)
+ : offset(offset),
+ beginRowId(beginRowId),
+ rowCount(rowCount),
+ taskBeginRowId(beginRowId),
+ taskRowCount(rowCount),
+ lastTaskBeginRowId(0),
+ lastTaskRowCount(0),
+ intersected(false) {}
+
+ COBlockTask(uint64_t offset, uint64_t beginRowId, uint64_t rowCount,
+ uint64_t taskBeginRowId, uint64_t taskRowCount)
+ : offset(offset),
+ beginRowId(beginRowId),
+ rowCount(rowCount),
+ taskBeginRowId(taskBeginRowId),
+ taskRowCount(taskRowCount),
+ lastTaskBeginRowId(0),
+ lastTaskRowCount(0),
+ intersected(false) {
+ LOG_DEBUG("CO block task %llu %llu %llu %llu %llu", offset, beginRowId,
+ rowCount, taskBeginRowId, taskRowCount);
+ }
+
+ typedef std::unique_ptr<COBlockTask> uptr;
+
+ public:
+ inline uint64_t getEndRowId() const { return beginRowId + rowCount - 1; }
+ inline uint64_t getTaskEndRowId() const {
+ return taskBeginRowId + taskRowCount - 1;
+ }
+ inline uint64_t getLastTaskEndRowId() const {
+ return lastTaskBeginRowId + lastTaskRowCount - 1;
+ }
+
+ inline void resetIntersection() {
+ intersected = false;
+ lastTaskBeginRowId = taskBeginRowId;
+ lastTaskRowCount = taskRowCount;
+ taskRowCount = 0;
+ }
+
+ inline void resetUnionAll() {
+ lastTaskBeginRowId = taskBeginRowId;
+ lastTaskRowCount = taskRowCount;
+ }
+
+ inline void intersect(const COBlockTask& srcTask) {
+ if (srcTask.getTaskEndRowId() < lastTaskBeginRowId ||
+ srcTask.taskBeginRowId > this->getLastTaskEndRowId()) {
+ if (!intersected) {
+ if (srcTask.getEndRowId() < this->lastTaskBeginRowId) {
+ // does not touch existing job, so restore original version
+ taskBeginRowId = lastTaskBeginRowId;
+ taskRowCount = lastTaskRowCount;
+ intersected = true;
+ } else if (srcTask.getEndRowId() <= this->getLastTaskEndRowId()) {
+ // restore partial job
+ taskBeginRowId = srcTask.getEndRowId() + 1;
+ taskRowCount = this->getLastTaskEndRowId() - taskBeginRowId + 1;
+ intersected = true;
+ }
+ return;
+ }
+ }
+
+ if (!intersected) {
+ // fix task begin row id, the source task may have smaller task begin row
+ // id, thus check to make sure this task has valid task begin row id. end
+ // row id has the same problem as well.
+ taskBeginRowId = srcTask.taskBeginRowId < taskBeginRowId
+ ? taskBeginRowId
+ : srcTask.taskBeginRowId;
+ uint64_t tmpTaskEndRowId = srcTask.getTaskEndRowId();
+ tmpTaskEndRowId = tmpTaskEndRowId > this->getLastTaskEndRowId()
+ ? this->getLastTaskEndRowId()
+ : tmpTaskEndRowId;
+ taskRowCount = tmpTaskEndRowId - taskBeginRowId + 1;
+ intersected = true;
+ } else {
+ // dont check begin row id again, as we expect srce tasks are processed
+ // in ascending order, and we use last task row id range to perform
+ // intersection
+ uint64_t tmpTaskEndRowId = srcTask.getTaskEndRowId();
+ tmpTaskEndRowId = tmpTaskEndRowId > this->getLastTaskEndRowId()
+ ? this->getLastTaskEndRowId()
+ : tmpTaskEndRowId;
+ taskRowCount = tmpTaskEndRowId - taskBeginRowId + 1;
+ }
+ }
+
+ inline void unionAll(const COBlockTask& srcTask) {
+ if (srcTask.getTaskEndRowId() < beginRowId ||
+ srcTask.taskBeginRowId > this->getEndRowId()) {
+ // skip this part, as no overlap in row id range
+ return;
+ }
+ // we always check its possible new begin rowid and it should not go out of
+ // current task range
+ taskBeginRowId = taskBeginRowId > srcTask.taskBeginRowId
+ ? srcTask.taskBeginRowId
+ : taskBeginRowId;
+ taskBeginRowId = taskBeginRowId < beginRowId ? beginRowId : taskBeginRowId;
+ // then is its end rowid
+ uint64_t tmpTaskEndRowId = srcTask.getTaskEndRowId();
+ tmpTaskEndRowId = tmpTaskEndRowId > this->getTaskEndRowId()
+ ? tmpTaskEndRowId
+ : this->getTaskEndRowId();
+ tmpTaskEndRowId = tmpTaskEndRowId > this->getEndRowId()
+ ? this->getEndRowId()
+ : tmpTaskEndRowId;
+ taskRowCount = tmpTaskEndRowId - taskBeginRowId + 1;
+ }
+
+ public:
+ uint64_t offset;
+ uint64_t beginRowId;
+ uint64_t rowCount;
+ uint64_t taskBeginRowId;
+ uint64_t taskRowCount;
+ uint64_t lastTaskBeginRowId;
+ uint64_t lastTaskRowCount;
+
+ private:
+ bool intersected;
+};
+
+class COBlockTaskList {
+ public:
+ COBlockTaskList();
+
+ void add(COBlockTask::uptr task) {
+ uint64_t taskBeginRowId = task->taskBeginRowId;
+ taskList[taskBeginRowId] = std::move(task);
+ }
+ void intersect(const COBlockTaskList& source);
+ void unionAll(const COBlockTaskList& source);
+
+ typedef std::unique_ptr<COBlockTaskList> uptr;
+
+ public:
+ std::map<uint64_t, COBlockTask::uptr> taskList;
+};
+
+class MinMaxPredicatesCO : public MinMaxPredicatesAbstract {
+ public:
+ MinMaxPredicatesCO(const univplan::UnivPlanExprPolyList* predicateExprs,
+ const dbcommon::TupleDesc* tupleDesc)
+ : MinMaxPredicatesAbstract(predicateExprs, tupleDesc) {}
+ virtual ~MinMaxPredicatesCO() {}
+
+ // methods implemented by sub-class to provide customized data preparation
+ virtual void preparePredicatesForStrip() = 0;
+ virtual COBlockTask::uptr buildCOTaskFromCurrentStrip(int colId) = 0;
+
+ // methods of whole calculation framework
+ virtual void preparePredicates();
+ virtual void calculate(std::unordered_map<int, COBlockTaskList::uptr>* res);
+
+ protected:
+ // holding one strip's statistics
+ std::unique_ptr<univplan::Statistics> stripStatistics;
+ // holding one page level predicates to do actual calculation
+ std::unique_ptr<MinMaxPredicatesPage> predicatesForPages;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_MINMAX_MINMAX_PREDICATES_H_
diff --git a/depends/univplan/src/univplan/proto/universal-plan-catalog.proto b/depends/univplan/src/univplan/proto/universal-plan-catalog.proto
new file mode 100644
index 0000000..eab5e16
--- /dev/null
+++ b/depends/univplan/src/univplan/proto/universal-plan-catalog.proto
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+syntax = "proto2";
+
+package univplan;
+
+option cc_generic_services = true;
+option java_generic_services = true;
+
+message UnivPlanColumn {
+ required string columnName = 1;
+ required int32 typeId = 2;
+ optional int32 scale1 = 3;
+ optional int32 scale2 = 4;
+ optional bool isNullable = 5;
+ optional bytes defaultVal = 6;
+ required int64 typeMod = 7 [default = -1];
+}
+
+enum UNIVPLANFORMATTYPE {
+ TEXT_FORMAT = 1;
+ CSV_FORMAT = 2;
+ ORC_FORMAT = 3;
+ MAGMA_FORMAT = 4;
+ MAGMA_LOCAL_FORMAT = 5;
+ INVALID_FORMAT = 6;
+}
+
+//
+// Magma:
+//
+// In case a Magma external table, location saves target table external
+// name defined in Magma, in format :
+// magma:///dbname/schemaname/tablename
+// for the columns, MAGMA has its own catalog having complete column definition,
+// thus, it is only required to fill basic column names and rough type content
+//
+
+message UnivPlanTable {
+ required int64 tableId = 1;
+ required UNIVPLANFORMATTYPE format = 2;
+ required string location = 3;
+ required bytes tableOptionsInJson = 4;
+ repeated UnivPlanColumn columns = 5;
+}
diff --git a/depends/univplan/src/univplan/proto/universal-plan-expr.proto b/depends/univplan/src/univplan/proto/universal-plan-expr.proto
new file mode 100644
index 0000000..bbd6b24
--- /dev/null
+++ b/depends/univplan/src/univplan/proto/universal-plan-expr.proto
@@ -0,0 +1,216 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+syntax = "proto2";
+
+package univplan;
+
+option cc_generic_services = true;
+option java_generic_services = true;
+
+enum UNIVPLANEXPRTYPE {
+ UNIVPLAN_EXPR_AGGREF = 1;
+ UNIVPLAN_EXPR_BOOLEXPR = 2;
+ UNIVPLAN_EXPR_CONST = 3;
+ UNIVPLAN_EXPR_FUNCEXPR = 4;
+ UNIVPLAN_EXPR_NULLTEST = 5;
+ UNIVPLAN_EXPR_OPEXPR = 6;
+ UNIVPLAN_EXPR_TARGETENTRY = 7;
+ UNIVPLAN_EXPR_VAR = 8;
+ UNIVPLAN_EXPR_BOOLEANTEST = 9;
+ UNIVPLAN_EXPR_CASEEXPR = 10;
+ UNIVPLAN_EXPR_CASEWHEN = 11;
+ UNIVPLAN_EXPR_SUBPLAN = 12;
+ UNIVPLAN_EXPR_PARAM = 13;
+ UNIVPLAN_EXPR_SCALARARRAYOPEXPR = 14;
+ UNIVPLAN_EXPR_COALESCEEXPR = 15;
+ UNIVPLAN_EXPR_NULLIFEXPR = 16;
+ UNIVPLAN_EXPR_DISTINCTEXPR = 17;
+}
+
+message UnivPlanOpExpr {
+ required int32 funcId = 1;
+ required int32 retType = 2;
+ repeated UnivPlanExprPoly args = 3;
+}
+
+message UnivPlanFuncExpr {
+ required int32 funcId = 1;
+ required int32 retType = 2;
+ repeated UnivPlanExprPoly args = 3;
+}
+
+enum NULLTESTTYPE {
+ NULLTESTTYPE_IS_NULL = 0;
+ NULLTESTTYPE_IS_NOT_NULL = 1;
+}
+
+message UnivPlanNullTest {
+ required UnivPlanExprPoly arg = 1;
+ required NULLTESTTYPE type = 2;
+}
+
+enum BOOLTESTTYPE {
+ BOOLTESTTYPE_IS_TRUE = 0;
+ BOOLTESTTYPE_IS_NOT_TRUE = 1;
+ BOOLTESTTYPE_IS_FALSE = 2;
+ BOOLTESTTYPE_IS_NOT_FALSE = 3;
+ BOOLTESTTYPE_IS_UNKNOWN = 4;
+ BOOLTESTTYPE_IS_NOT_UNKNOWN = 5;
+}
+
+message UnivPlanBooleanTest {
+ required UnivPlanExprPoly arg = 1;
+ required BOOLTESTTYPE type = 2;
+}
+
+enum BOOLEXPRTYPE {
+ BOOLEXPRTYPE_AND_EXPR = 0;
+ BOOLEXPRTYPE_OR_EXPR = 1;
+ BOOLEXPRTYPE_NOT_EXPR = 2;
+}
+
+message UnivPlanBoolExpr {
+ repeated UnivPlanExprPoly args = 1;
+ required BOOLEXPRTYPE type = 2;
+}
+
+message UnivPlanConst {
+ required int32 type = 1;
+ required bool isNull = 2;
+ optional string value = 3;
+ optional int64 typeMod = 4 [default = -1];
+}
+
+message UnivPlanVar {
+ required uint32 varNo = 1;
+ required int32 varAttNo = 2;
+ required int32 typeId = 3;
+ optional int64 typeMod = 4 [default = -1];
+}
+
+message UnivPlanAggref {
+ required int32 transFuncId = 1;
+ required int32 retType = 2;
+ required bool transInitVal = 3;
+ optional int32 finalFuncId = 4;
+ repeated UnivPlanExprPoly args = 5;
+ required int32 funcId = 6;
+}
+
+message UnivPlanTargetEntry {
+ required UnivPlanExprPoly expression = 1;
+ required bool resJunk = 2;
+ optional string resName = 3;
+}
+
+message UnivPlanCaseExpr {
+ required int32 casetype = 1;
+ repeated UnivPlanExprPoly args = 2;
+ required UnivPlanExprPoly defresult = 3;
+}
+
+message UnivPlanCaseWhen {
+ required UnivPlanExprPoly expr = 1;
+ required UnivPlanExprPoly result = 2;
+}
+
+enum SUBLINKTYPE {
+ EXISTS_SUBLINK = 0;
+ ALL_SUBLINK = 1;
+ ANY_SUBLINK = 2;
+ ROWCOMPARE_SUBLINK = 3;
+ EXPR_SUBLINK = 4;
+ ARRAY_SUBLINK = 5;
+ NOT_EXISTS_SUBLINK = 6;
+}
+
+message UnivPlanSubPlan {
+ required SUBLINKTYPE subLinkType = 1;
+ required int32 planId = 2;
+ required int32 typeId = 3;
+ optional int64 typeMod = 4 [default = -1];
+ required bool useHashTable = 5;
+ required bool initPlan = 6;
+ repeated int32 setParam = 7; // input param for param_exec
+ repeated int32 parentParam = 8; // input param for subplan
+ repeated UnivPlanExprPoly args = 9; // inputs for subplan
+ repeated int32 testexprParam = 10; // input param for test expr
+ optional UnivPlanExprPoly testexpr = 11; // test expr for ALL/ANY
+}
+
+enum PARAMKIND {
+ PARAM_EXTERN = 0;
+ PARAM_EXEC = 1;
+}
+
+message UnivPlanParam {
+ required PARAMKIND paramKind = 1;
+ required int32 paramId = 2;
+ required int32 typeId = 3;
+ optional int64 typeMod = 4 [default = -1];
+}
+
+message UnivPlanScalarArrayOpExpr {
+ required int32 funcId = 1;
+ required bool useOr = 2;
+ repeated UnivPlanExprPoly args = 3;
+}
+
+message UnivPlanCoalesceExpr {
+ required int32 coalesceType = 1;
+ required int32 coalesceTypeMod = 2;
+ repeated UnivPlanExprPoly args = 3;
+}
+
+message UnivPlanNullIfExpr {
+ required int32 funcId = 1;
+ required int32 retType = 2;
+ required int32 typeMod = 3;
+ repeated UnivPlanExprPoly args = 4;
+}
+
+message UnivPlanDistinctExpr {
+ required int32 funcId = 1;
+ required int32 retType = 2;
+ repeated UnivPlanExprPoly args = 3;
+}
+
+message UnivPlanExprPoly {
+ required UNIVPLANEXPRTYPE type = 1;
+ oneof value {
+ UnivPlanAggref aggref = 2;
+ UnivPlanBoolExpr boolexpr = 3;
+ UnivPlanConst val = 4;
+ UnivPlanFuncExpr funcexpr = 5;
+ UnivPlanNullTest nulltest = 6;
+ UnivPlanOpExpr opexpr = 7;
+ UnivPlanTargetEntry targetentry = 8;
+ UnivPlanVar var = 9;
+ UnivPlanBooleanTest booltest = 10;
+ UnivPlanCaseExpr caseexpr = 11;
+ UnivPlanCaseWhen casewhen = 12;
+ UnivPlanSubPlan subplan = 13;
+ UnivPlanParam param = 14;
+ UnivPlanScalarArrayOpExpr scalarArrayOpexpr = 15;
+ UnivPlanCoalesceExpr coalesceExpr = 16;
+ UnivPlanNullIfExpr nullIfExpr = 17;
+ UnivPlanDistinctExpr distinctExpr = 18;
+ }
+}
diff --git a/depends/univplan/src/univplan/proto/universal-plan.proto b/depends/univplan/src/univplan/proto/universal-plan.proto
new file mode 100644
index 0000000..fb1cf95
--- /dev/null
+++ b/depends/univplan/src/univplan/proto/universal-plan.proto
@@ -0,0 +1,415 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+syntax = "proto2";
+
+package univplan;
+
+option cc_generic_services = true;
+option java_generic_services = true;
+
+import "univplan/proto/universal-plan-catalog.proto";
+import "univplan/proto/universal-plan-expr.proto";
+
+enum UNIVPLANNODETYPE {
+ UNIVPLAN_UNSET = 1;
+
+ UNIVPLAN_CONNECTOR = 2;
+ UNIVPLAN_SINK = 3;
+ UNIVPLAN_CONVERGE = 4;
+ UNIVPLAN_BROADCAST = 5;
+ UNIVPLAN_SHUFFLE = 6;
+ UNIVPLAN_AGG = 7;
+ UNIVPLAN_SCAN_SEQ = 8;
+ UNIVPLAN_SORT = 9;
+ UNIVPLAN_LIMIT = 10;
+ UNIVPLAN_APPEND = 11;
+ UNIVPLAN_NESTLOOP = 12;
+ UNIVPLAN_HASHJOIN = 13;
+ UNIVPLAN_MERGEJOIN = 14;
+ UNIVPLAN_MATERIAL = 15;
+ UNIVPLAN_RESULT = 16;
+ UNIVPLAN_HASH = 17;
+ UNIVPLAN_SUBQUERYSCAN = 18;
+ UNIVPLAN_UNIQUE = 19;
+ UNIVPLAN_INSERT = 20;
+ UNIVPLAN_SHAREINPUTSCAN = 21;
+
+ UNIVPLAN_EXT_GS_SCAN = 100;
+ UNIVPLAN_EXT_GS_FILTER = 101;
+ UNIVPLAN_EXT_GS_PROJ = 102;
+}
+
+message UnivPlanPlanNodePoly {
+ required UNIVPLANNODETYPE type = 1;
+ oneof value {
+ UnivPlanConnector connector = 2;
+ UnivPlanSink sink = 3;
+ UnivPlanConverge converge = 4;
+ UnivPlanBroadcast broadcast = 5;
+ UnivPlanShuffle shuffle = 6;
+ UnivPlanAgg agg = 7;
+ UnivPlanScanSeq scanSeq = 8;
+ UnivPlanSort sort = 9;
+ UnivPlanLimit limit = 10;
+ UnivPlanAppend append = 11;
+ UnivPlanNestLoop nestLoop = 12;
+ UnivPlanMergeJoin mergeJoin = 13;
+ UnivPlanHashJoin hashJoin = 14;
+ UnivPlanMaterial material = 15;
+ UnivPlanResult result = 16;
+ UnivPlanHash hash = 17;
+ UnivPlanSubqueryScan subqueryscan = 18;
+ UnivPlanUnique unique = 19;
+ UnivPlanInsert insert = 20;
+ UnivPlanShareInputScan shareinputscan = 21;
+
+ UnivPlanExtGSScan extGSScan = 100;
+ UnivPlanExtGSFilter extGSFilter = 101;
+ UnivPlanExtGSProj extGSProject = 102;
+ }
+}
+
+// The overall super node for plan nodes
+message UnivPlanPlanNode {
+ repeated UnivPlanExprPoly targetList = 1; // Target list to be calculated
+ repeated UnivPlanExprPoly qualList = 2; // qual conditions
+ optional UnivPlanPlanNodePoly leftPlan = 3; // left plan tree
+ optional UnivPlanPlanNodePoly rightPlan = 4; // right plan tree
+ repeated UnivPlanExprPoly initPlan = 5; // un-correlated expr subselects
+ optional double planRows = 6; // estimated number of rows
+ optional int32 planRowWidth = 7; // estimated row width in bytes
+ optional int64 operatorMemKB = 8;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SCAN NODES BEGIN
+///////////////////////////////////////////////////////////////////////////////
+
+// The scan task
+message UnivPlanScanTask {
+ // repeated UnivPlanScanFileSplit splits = 1;
+ optional bytes serializedSplits = 1;
+}
+
+message UnivPlanScanSeq {
+ required UnivPlanPlanNode super = 1;
+ required uint32 relId = 2;
+ optional bool readStatsOnly = 3;
+ repeated UnivPlanScanTask tasks = 4;
+ repeated int32 columnsToRead = 5;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SCAN NODES END
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// SINK NODES BEGIN
+///////////////////////////////////////////////////////////////////////////////
+
+enum UNIVPLANCONNECTORTYPE {
+ CONNECTORTYPE_INVALID = 0;
+ CONNECTORTYPE_SHUFFLE = 1;
+ CONNECTORTYPE_BROADCAST = 2;
+ CONNECTORTYPE_CONVERGE = 3;
+}
+
+message UnivPlanConnector {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANCONNECTORTYPE type = 2;
+ optional int32 stageno = 3 [default = -1];
+ repeated UnivPlanExprPoly hashExpr = 4;
+ repeated int32 colIdx = 5;
+ repeated int32 sortFuncId = 6;
+ optional bool magmaTable = 7 [default = false];
+ repeated int32 magmaMap = 8;
+ optional int32 rangeNum = 9 [default = 0]; // magma range num
+}
+
+// Sink
+message UnivPlanSink {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANCONNECTORTYPE connectorType = 2;
+ required int32 sourceStageNo = 3;
+ required int32 currentStageNo = 4;
+ repeated int32 colIdx = 5;
+ repeated int32 sortFuncId = 6;
+}
+
+// Converge
+message UnivPlanConverge {
+ required UnivPlanPlanNode super = 1;
+ required int32 targetStageNo = 2;
+ required int32 currentStageNo = 3;
+}
+
+// Broadcast
+message UnivPlanBroadcast {
+ required UnivPlanPlanNode super = 1;
+ required int32 targetStageNo = 2;
+ required int32 currentStageNo = 3;
+}
+
+// Shuffle
+message UnivPlanShuffle {
+ required UnivPlanPlanNode super = 1;
+ required int32 targetStageNo = 2;
+ required int32 currentStageNo = 3;
+ repeated UnivPlanExprPoly hashExpr = 4;
+ optional bool magmaTable = 5 [default = false];
+ repeated int32 magmaMap = 6;
+ optional int32 rangeNum = 9 [default = 0]; // magma range num
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SINK NODES END
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// JOIN NODES BEGIN
+///////////////////////////////////////////////////////////////////////////////
+
+enum UNIVPLANJOINTYPE {
+ JOIN_INNER = 0; // matching tuple pairs only
+ JOIN_LEFT = 1; // pairs + unmatched LHS tuples
+ JOIN_RIGHT = 2; // pairs + unmatched RHS tuples
+ JOIN_FULL = 3; // pairs + unmatched LHS + unmatched RHS
+ JOIN_IN = 4;
+ JOIN_LASJ = 8;
+ JOIN_LASJ_NOTIN = 9;
+ JOIN_NOT_SUPPORTED = 10;
+}
+
+// NestLoop
+message UnivPlanNestLoop {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANJOINTYPE type = 2;
+ repeated UnivPlanExprPoly joinQual = 3;
+}
+
+// HashJoin
+message UnivPlanHashJoin {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANJOINTYPE type = 2;
+ repeated UnivPlanExprPoly joinQual = 3;
+ repeated UnivPlanExprPoly hashClauses = 4;
+ repeated UnivPlanExprPoly hashQualClauses = 5;
+}
+
+// MergeJoin
+message UnivPlanMergeJoin {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANJOINTYPE type = 2;
+ repeated UnivPlanExprPoly joinQual = 3;
+ repeated UnivPlanExprPoly mergeClauses = 4;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// JOIN NODES END
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// OTHER PLAN NODES BEGIN
+///////////////////////////////////////////////////////////////////////////////
+
+message UnivPlanAgg {
+ required UnivPlanPlanNode super = 1;
+ required int64 numGroups = 2;
+ repeated int32 groupColIndexes = 3;
+}
+
+message UnivPlanLimit {
+ required UnivPlanPlanNode super = 1;
+ optional UnivPlanExprPoly limitOffset = 2;
+ optional UnivPlanExprPoly limitCount = 3;
+}
+
+message UnivPlanAppend {
+ required UnivPlanPlanNode super = 1;
+ repeated UnivPlanPlanNodePoly appendPlans = 2;
+}
+
+message UnivPlanSort {
+ required UnivPlanPlanNode super = 1;
+ repeated int32 colIdx = 2;
+ repeated int32 sortFuncId = 3;
+ optional UnivPlanExprPoly limitOffset = 4;
+ optional UnivPlanExprPoly limitCount = 5;
+}
+
+enum UNIVPLANSHARETYPE {
+ SHARE_NOTSHARED = 0;
+ SHARE_MATERIAL = 1;
+ SHARE_MATERIAL_XSLICE = 2;
+ SHARE_SORT = 3;
+ SHARE_SORT_XSLICE = 4;
+ SHARE_NOT_SUPPORTED = 5;
+}
+
+message UnivPlanMaterial {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANSHARETYPE share_type = 2;
+ required bool cdbStrict = 3;
+ optional int32 shared_id = 4;
+ optional int32 driver_slice = 5; // slice id that will execute this material
+ optional int32 nsharer = 6; // number of sharer
+ optional int32 nsharer_xslice = 7; // number of sharer cross slice
+}
+
+message UnivPlanShareInputScan {
+ required UnivPlanPlanNode super = 1;
+ required UNIVPLANSHARETYPE shareType = 2;
+ required int32 sharedId = 3;
+ required int32 driverSlice = 4;
+}
+
+message UnivPlanResult {
+ required UnivPlanPlanNode super = 1;
+ repeated UnivPlanExprPoly resconstantqual = 2;
+}
+
+message UnivPlanHash {
+ required UnivPlanPlanNode super = 1;
+}
+
+message UnivPlanSubqueryScan {
+ required UnivPlanPlanNode super = 1;
+ optional UnivPlanPlanNodePoly subPlan = 2;
+}
+
+message UnivPlanUnique {
+ required UnivPlanPlanNode super = 1;
+ repeated int32 uniqColIdxs = 2;
+}
+
+message UnivPlanInsert {
+ required UnivPlanPlanNode super = 1;
+ required uint32 relId = 2;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// OTHER PLAN NODES END
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// MAGMA NODES BEGIN
+///////////////////////////////////////////////////////////////////////////////
+enum ExternalScanType {
+ TableScan = 0;
+ MagmaIndexScan = 1;
+ MagmaIndexOnlyScan = 2;
+ MagmaBitmapScan = 3;
+}
+
+enum ExternalScanDirection {
+ BackwardScanDirection = -1;
+ NoMovementScanDirection = 0;
+ ForwardScanDirection = 1;
+}
+
+message UnivPlanExtGSScan {
+ required UnivPlanPlanNode super = 1;
+ required uint32 relId = 2; // table def index
+ repeated int32 keyColIndex = 3; // this two field for schema mapping
+ repeated int32 valColIndex = 4;
+ repeated int32 columnsToRead = 5;
+ optional UnivPlanExprPoly filter = 6; // filter
+ repeated UnivPlanExprPoly filterByKeyCol = 7; // filter for each col
+ repeated UnivPlanScanTask tasks = 8; // use univplan scan task
+ // index scan info for magma
+ optional bool indexscan = 9 [default = false];
+ optional ExternalScanType type = 10;
+ optional ExternalScanDirection direction = 11;
+ optional string indexName = 12;
+ repeated UnivPlanExprPoly indexQual = 13;
+ optional bool readStatsOnly = 14 [default = false];
+}
+
+message UnivPlanExtGSFilter {
+ required UnivPlanPlanNode super = 1;
+ optional UnivPlanExprPoly filter = 2; // filter for all columns
+}
+
+message UnivPlanExtGSProj {
+ required UnivPlanPlanNode super = 1;
+ repeated int32 columnIndexes = 2; // required columns
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// MAGMA NODES END
+///////////////////////////////////////////////////////////////////////////////
+
+message UnivPlanRangeTblEntry {
+ required UnivPlanTable table = 1;
+}
+
+message UnivPlanListener {
+ required string address = 1;
+ required int32 port = 2;
+}
+
+message UnivPlanReceiver {
+ repeated UnivPlanListener listener = 1;
+}
+
+message UnivPlanParamInfo {
+ required int32 type = 1;
+ required bool isNull = 2;
+ optional string value = 3;
+}
+
+message UnivPlanTokenKey {
+ required string protocol = 1;
+ required string ip = 2;
+ required int32 port = 3;
+}
+
+message UnivPlanTokenEntry {
+ required UnivPlanTokenKey key = 1;
+ required string token = 2;
+}
+
+enum UNIVPLANCMDTYPE {
+ CMD_UNKNOWN = 0;
+ CMD_SELECT = 1;
+ CMD_UPDATE = 2;
+ CMD_INSERT = 3;
+ CMD_DELETE = 4;
+ CMD_UTILITY = 5;
+ CMD_NOTHING = 6;
+}
+
+// Overall container of one plan to execute
+message UnivPlanPlan {
+ required UnivPlanPlanNodePoly plan = 1;
+ repeated UnivPlanPlan childStages = 2;
+ repeated UnivPlanRangeTblEntry rangeTables = 3;
+ repeated UnivPlanReceiver receivers = 4;
+ optional int32 stageNo = 5;
+ optional bool doInstrument = 6;
+ repeated UnivPlanPlanNodePoly subplans = 7;
+ repeated UnivPlanParamInfo paramInfos = 8;
+ optional int32 nCrossLevelParams = 9 [default = 0];
+ repeated UnivPlanTokenEntry tokenMap = 10;
+ optional bytes snapshot = 11;
+ map<string, string> guc = 12;
+ map<string, string> commonValue = 13;
+ optional UNIVPLANCMDTYPE cmdType = 14 [default = CMD_SELECT];
+}
diff --git a/depends/univplan/src/univplan/testutil/univplan-proto-util.cc b/depends/univplan/src/univplan/testutil/univplan-proto-util.cc
new file mode 100644
index 0000000..6bb0a76
--- /dev/null
+++ b/depends/univplan/src/univplan/testutil/univplan-proto-util.cc
@@ -0,0 +1,519 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/testutil/univplan-proto-util.h"
+
+#include <memory>
+#include <string>
+
+#include "dbcommon/function/func-kind.cg.h"
+
+namespace univplan {
+
+UnivPlanProtoUtility::UnivPlanProtoUtility() {
+ this->univplan = univPlanNewInstance();
+}
+
+UnivPlanProtoUtility::~UnivPlanProtoUtility() {
+ univPlanFreeInstance(&univplan);
+}
+
+void UnivPlanProtoUtility::constructVarOpConstExpr(
+ int32_t pid, int32_t opFuncId, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType, dbcommon::TypeKind constType,
+ const char *buffer) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddOpExpr(univplan, pid, opFuncId);
+ univPlanExprAddVar(univplan, root, varNo, varAttNo, varType, -1);
+ univPlanExprAddConst(univplan, root, constType, false, buffer, -1);
+}
+
+void UnivPlanProtoUtility::constructConstOpVarExpr(
+ int32_t pid, int32_t opFuncId, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType, dbcommon::TypeKind constType,
+ const char *buffer) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddOpExpr(univplan, pid, opFuncId);
+ univPlanExprAddConst(univplan, root, constType, false, buffer, -1);
+ univPlanExprAddVar(univplan, root, varNo, varAttNo, varType, -1);
+}
+
+void UnivPlanProtoUtility::constructVarOpVarExpr(
+ int32_t pid, int32_t opFuncId, int32_t varNo1, int32_t varAttNo1,
+ dbcommon::TypeKind varType1, int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddOpExpr(univplan, pid, opFuncId);
+ univPlanExprAddVar(univplan, root, varNo1, varAttNo1, varType1, -1);
+ univPlanExprAddVar(univplan, root, varNo2, varAttNo2, varType2, -1);
+}
+
+void UnivPlanProtoUtility::constructConstOpConstExpr(
+ int32_t pid, int32_t opFuncId, dbcommon::TypeKind constType1,
+ const char *buffer1, dbcommon::TypeKind constType2, const char *buffer2) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddOpExpr(univplan, pid, opFuncId);
+ univPlanExprAddConst(univplan, root, constType1, false, buffer1, -1);
+ univPlanExprAddConst(univplan, root, constType2, false, buffer2, -1);
+}
+
+void UnivPlanProtoUtility::constructFuncOpVarExpr(int32_t pid, int32_t opFuncId,
+ int32_t varNo,
+ int32_t varAttNo,
+ dbcommon::TypeKind varType,
+ int32_t mappingFuncId) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddOpExpr(univplan, pid, opFuncId);
+ univPlanExprAddFuncExpr(univplan, root, mappingFuncId);
+ univPlanExprAddVar(univplan, root, varNo, varAttNo, varType, -1);
+}
+
+void UnivPlanProtoUtility::constructBoolExpr(
+ int32_t pid, int32_t opFuncId1, int32_t varNo1, int32_t varAttNo1,
+ dbcommon::TypeKind varType1, dbcommon::TypeKind constType1,
+ const char *buffer1, int32_t opFuncId2, int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2, dbcommon::TypeKind constType2,
+ const char *buffer2, int8_t boolType) {
+ univPlanNewExpr(univplan);
+ int32_t root =
+ univPlanExprAddBoolExpr(univplan, pid, UnivplanBoolExprType(boolType));
+
+ int32_t root1 = univPlanExprAddOpExpr(univplan, root, opFuncId1);
+ univPlanExprAddVar(univplan, root1, varNo1, varAttNo1, varType1, -1);
+ univPlanExprAddConst(univplan, root1, constType1, false, buffer1, -1);
+
+ int32_t root2 = univPlanExprAddOpExpr(univplan, root, opFuncId2);
+ univPlanExprAddVar(univplan, root2, varNo2, varAttNo2, varType2, -1);
+ univPlanExprAddConst(univplan, root2, constType2, false, buffer2, -1);
+}
+
+void UnivPlanProtoUtility::constructNullTestExpr(int32_t pid,
+ int8_t nulltesttype,
+ int32_t varNo,
+ int32_t varAttNo,
+ dbcommon::TypeKind varType) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddNullTestExpr(
+ univplan, pid, UnivplanNullTestType(nulltesttype));
+ univPlanExprAddVar(univplan, root, varNo, varAttNo, varType, -1);
+}
+
+void UnivPlanProtoUtility::constructVarOpConstThenOpVarOpConstExpr(
+ int32_t pid, int32_t opFuncId, int32_t opFuncId1, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ dbcommon::TypeKind constType1, const char *buffer1, int32_t opFuncId2,
+ int32_t varNo2, int32_t varAttNo2, dbcommon::TypeKind varType2,
+ dbcommon::TypeKind constType2, const char *buffer2) {
+ univPlanNewExpr(univplan);
+ int32_t root = univPlanExprAddOpExpr(univplan, pid, opFuncId);
+
+ int32_t root1 = univPlanExprAddOpExpr(univplan, root, opFuncId1);
+ univPlanExprAddVar(univplan, root1, varNo1, varAttNo1, varType1, -1);
+ univPlanExprAddConst(univplan, root1, constType1, false, buffer1, -1);
+
+ int32_t root2 = univPlanExprAddOpExpr(univplan, root, opFuncId2);
+ univPlanExprAddVar(univplan, root2, varNo2, varAttNo2, varType2, -1);
+ univPlanExprAddConst(univplan, root2, constType2, false, buffer2, -1);
+}
+
+void UnivPlanProtoUtility::constructVarTargetEntry(int32_t pid, int32_t varNo,
+ int32_t varAttNo,
+ dbcommon::TypeKind type) {
+ univPlanNewExpr(univplan);
+ univPlanExprAddVar(univplan, pid, varNo, varAttNo, type, -1);
+ univPlanTargetListAddTargetEntry(univplan, false);
+}
+
+void UnivPlanProtoUtility::constructConstTargetEntry(
+ int32_t pid, dbcommon::TypeKind constType, const char *buffer) {
+ univPlanNewExpr(univplan);
+ if (constType == dbcommon::TypeKind::ANYID)
+ univPlanExprAddConst(univplan, -1, dbcommon::TypeKind::TINYINTID, true,
+ buffer, -1);
+ else
+ univPlanExprAddConst(univplan, -1, constType, false, buffer, -1);
+ univPlanTargetListAddTargetEntry(univplan, false);
+}
+
+void UnivPlanProtoUtility::constructConstOpConstTargetEntry(
+ int32_t pid, int32_t opFuncId, dbcommon::TypeKind constType1,
+ const char *buffer1, dbcommon::TypeKind constType2, const char *buffer2) {
+ univPlanNewExpr(univplan);
+ constructConstOpConstExpr(pid, opFuncId, constType1, buffer1, constType2,
+ buffer2);
+ univPlanTargetListAddTargetEntry(univplan, false);
+}
+
+void UnivPlanProtoUtility::constructAggRefTargetEntry(
+ int32_t pid, int8_t aggstage, int32_t mappingFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind type) {
+ univPlanNewExpr(univplan);
+ int32_t uid;
+ if (aggstage == 1) // AGGSTAGE_PARTIAL
+ uid = univPlanAggrefAddPartialStage(univplan, -1, mappingFuncId);
+ else if (aggstage == 3) // AGGSTAGE_FINAL
+ uid = univPlanAggrefAddFinalStage(univplan, -1, mappingFuncId);
+ univPlanAggrefAddProxyVar(univplan, uid, varAttNo, mappingFuncId, -1);
+ univPlanTargetListAddTargetEntry(univplan, false);
+}
+
+void UnivPlanProtoUtility::constructNullTestTargetEntry(
+ int32_t pid, int8_t nulltesttype, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType) {
+ constructNullTestExpr(pid, nulltesttype, varNo, varAttNo, varType);
+ univPlanTargetListAddTargetEntry(univplan, false);
+}
+
+void UnivPlanProtoUtility::constructVarOpConstTargetEntry(
+ int32_t pid, int32_t opFuncId, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType, dbcommon::TypeKind constType,
+ const char *buffer) {
+ constructVarOpConstExpr(pid, opFuncId, varNo, varAttNo, varType, constType,
+ buffer);
+ univPlanTargetListAddTargetEntry(univplan, false);
+}
+
+void UnivPlanProtoUtility::constructVarOpConstQualList(
+ int32_t pid, int32_t opFuncId, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType, dbcommon::TypeKind constType,
+ const char *buffer) {
+ constructVarOpConstExpr(pid, opFuncId, varNo, varAttNo, varType, constType,
+ buffer);
+ univPlanQualListAddExpr(univplan);
+}
+
+void UnivPlanProtoUtility::constructConstOpVarQualList(
+ int32_t pid, int32_t opFuncId, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType, dbcommon::TypeKind constType,
+ const char *buffer) {
+ constructConstOpVarExpr(pid, opFuncId, varNo, varAttNo, varType, constType,
+ buffer);
+ univPlanQualListAddExpr(univplan);
+}
+
+void UnivPlanProtoUtility::constructVarOpVarQualList(
+ int32_t pid, int32_t opFuncId, int32_t varNo1, int32_t varAttNo1,
+ dbcommon::TypeKind varType1, int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2) {
+ constructVarOpVarExpr(pid, opFuncId, varNo1, varAttNo1, varType1, varNo2,
+ varAttNo2, varType2);
+ univPlanQualListAddExpr(univplan);
+}
+
+void UnivPlanProtoUtility::constructFuncOpVarQualList(
+ int32_t pid, int32_t opFuncId, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType, int32_t mappingFuncId) {
+ constructFuncOpVarExpr(pid, opFuncId, varNo, varAttNo, varType,
+ mappingFuncId);
+ univPlanQualListAddExpr(univplan);
+}
+
+void UnivPlanProtoUtility::constructBoolQualList(
+ int32_t pid, int32_t opFuncId1, int32_t varNo1, int32_t varAttNo1,
+ dbcommon::TypeKind varType1, dbcommon::TypeKind constType1,
+ const char *buffer1, int32_t opFuncId2, int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2, dbcommon::TypeKind constType2,
+ const char *buffer2, int8_t boolType) {
+ constructBoolExpr(pid, opFuncId1, varNo1, varAttNo1, varType1, constType1,
+ buffer1, opFuncId2, varNo2, varAttNo2, varType2, constType2,
+ buffer2, boolType);
+ univPlanQualListAddExpr(univplan);
+}
+
+void UnivPlanProtoUtility::constructNullTestQualList(
+ int32_t pid, int8_t nulltesttype, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType) {
+ constructNullTestExpr(pid, nulltesttype, varNo, varAttNo, varType);
+ univPlanQualListAddExpr(univplan);
+}
+
+void UnivPlanProtoUtility::constructVarOpConstThenOpVarOpConstQualList(
+ int32_t pid, int32_t opFuncId, int32_t opFuncId1, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ dbcommon::TypeKind constType1, const char *buffer1, int32_t opFuncId2,
+ int32_t varNo2, int32_t varAttNo2, dbcommon::TypeKind varType2,
+ dbcommon::TypeKind constType2, const char *buffer2) {
+ constructVarOpConstThenOpVarOpConstExpr(
+ pid, opFuncId, opFuncId1, varNo1, varAttNo1, varType1, constType1,
+ buffer1, opFuncId2, varNo2, varAttNo2, varType2, constType2, buffer2);
+ univPlanQualListAddExpr(univplan);
+}
+
+int32_t UnivPlanProtoUtility::constructSeqScan(int32_t pid, bool withQualList,
+ int8_t targetEntryType) {
+ int32_t uid = ::univPlanSeqScanNewInstance(univplan, pid);
+
+ constructVarTargetEntry(-1, 1, 1, dbcommon::TypeKind::INTID);
+ if (targetEntryType == 0) {
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+ } else if (targetEntryType == 1) {
+ constructVarTargetEntry(-1, 1, 2, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+ } else if (targetEntryType == 2) {
+ constructNullTestTargetEntry(-1, 1, 1, 3, dbcommon::TypeKind::STRINGID);
+ } else if (targetEntryType == 3) {
+ constructVarOpConstTargetEntry(-1, dbcommon::INT_ADD_INT, 1, 1,
+ dbcommon::TypeKind::INTID,
+ dbcommon::TypeKind::INTID, "1");
+ } else if (targetEntryType == 4) {
+ constructVarOpConstTargetEntry(-1, dbcommon::STRING_EQUAL_STRING, 1, 3,
+ dbcommon::TypeKind::STRINGID,
+ dbcommon::TypeKind::STRINGID, "1");
+ } else if (targetEntryType == 5) {
+ constructConstTargetEntry(-1, dbcommon::TypeKind::BIGINTID, "1");
+ } else if (targetEntryType == 6) {
+ constructConstTargetEntry(-1, dbcommon::TypeKind::ANYID, "");
+ } else if (targetEntryType == 7) {
+ constructVarOpConstTargetEntry(-1, dbcommon::INT_ADD_INT, 1, 1,
+ dbcommon::TypeKind::INTID,
+ dbcommon::TypeKind::INTID, "1");
+ constructVarOpConstTargetEntry(-1, dbcommon::STRING_EQUAL_STRING, 1, 3,
+ dbcommon::TypeKind::STRINGID,
+ dbcommon::TypeKind::STRINGID, "1");
+ } else if (targetEntryType == 8) {
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+ constructVarTargetEntry(-1, 1, 2, dbcommon::TypeKind::INTID);
+ }
+
+ if (withQualList) {
+ constructVarOpConstQualList(-1, dbcommon::INT_GREATER_THAN_INT, 1, 2,
+ dbcommon::TypeKind::INTID,
+ dbcommon::TypeKind::INTID, "1");
+ constructVarOpVarQualList(-1, dbcommon::BIGINT_EQUAL_INT, 1, 1,
+ dbcommon::TypeKind::INTID, 1, 2,
+ dbcommon::TypeKind::INTID);
+ constructFuncOpVarQualList(-1, dbcommon::DOUBLE_LESS_THAN_DOUBLE, 1, 1,
+ dbcommon::TypeKind::INTID,
+ dbcommon::TINYINT_LESS_THAN_TINYINT);
+ constructBoolQualList(
+ -1, dbcommon::BIGINT_GREATER_THAN_INT, 1, 1, dbcommon::TypeKind::INTID,
+ dbcommon::TypeKind::INTID, "1", dbcommon::INT_LESS_THAN_INT, 1, 2,
+ dbcommon::TypeKind::INTID, dbcommon::TypeKind::INTID, "10");
+ }
+
+ univPlanSeqScanSetRelId(univplan, 1);
+
+ int32_t numCols = 2;
+ int32_t *columnsToRead =
+ reinterpret_cast<int32_t *>(malloc(numCols * sizeof(int32_t)));
+ columnsToRead[0] = 0;
+ columnsToRead[1] = 1;
+ univPlanSeqScanSetColumnsToRead(univplan, numCols, columnsToRead);
+ free(columnsToRead);
+
+ int64_t start[2] = {1, 2};
+ int64_t len[2] = {200, 100};
+ std::string fileName_buf[2] = {"/a", "/b"};
+ std::unique_ptr<const char *[]> fileName(new const char *[2]);
+ fileName[0] = fileName_buf[0].c_str();
+ fileName[1] = fileName_buf[1].c_str();
+ univPlanSeqScanAddTaskWithFileSplits(false, univplan, 1, fileName.get(),
+ start, len, NULL, NULL);
+ univPlanSeqScanAddTaskWithFileSplits(false, univplan, 2, fileName.get(),
+ start, len, NULL, NULL);
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+int32_t UnivPlanProtoUtility::constructConnector(int32_t pid, int8_t ctype,
+ bool allTargetEntry) {
+ int32_t uid = univPlanConnectorNewInstance(univplan, pid);
+ univPlanConnectorSetType(univplan, ConnectorType(ctype));
+
+ constructVarTargetEntry(-1, 1, 1, dbcommon::TypeKind::INTID);
+ if (allTargetEntry)
+ constructVarTargetEntry(-1, 1, 2, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+
+ if (ctype == 0) {
+ univPlanNewExpr(univplan);
+ univPlanExprAddVar(univplan, -1, 1, 0, dbcommon::TypeKind::INTID, -1);
+ univPlanConnectorAddHashExpr(univplan);
+ }
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+int32_t UnivPlanProtoUtility::constructSortConnector(int32_t pid,
+ int8_t ctype) {
+ int32_t uid = univPlanConnectorNewInstance(univplan, pid);
+ univPlanConnectorSetType(univplan, ConnectorType(ctype));
+
+ constructVarTargetEntry(-1, 1, 1, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+
+ int64_t numCols = 2;
+ int32_t *colIdx =
+ reinterpret_cast<int32_t *>(malloc(numCols * sizeof(int32_t)));
+ int32_t *mappingSortFuncId =
+ reinterpret_cast<int32_t *>(malloc(numCols * sizeof(int32_t)));
+ colIdx[0] = 1;
+ colIdx[1] = 2;
+ mappingSortFuncId[0] = dbcommon::BIGINT_LESS_THAN_BIGINT;
+ mappingSortFuncId[1] = dbcommon::INT_LESS_THAN_INT;
+ univPlanConnectorSetColIdx(univplan, numCols, colIdx);
+ univPlanConnectorSetSortFuncId(univplan, numCols, mappingSortFuncId);
+ free(colIdx);
+ free(mappingSortFuncId);
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+int32_t UnivPlanProtoUtility::constructLimitBelow(int32_t pid, int64_t count,
+ int64_t offset) {
+ int32_t uid = univPlanLimitNewInstance(univplan, pid);
+
+ constructVarTargetEntry(-1, 1, 1, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 2, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+
+ univPlanSetPlanNodeInfo(univplan, static_cast<double>(count + offset), 0, 0);
+
+ std::string countTmp = std::to_string(count);
+ char const *countBuf = countTmp.c_str();
+ std::string offsetTmp = std::to_string(offset);
+ char const *offsetBuf = offsetTmp.c_str();
+ if (count != -1) {
+ constructConstOpConstExpr(-1, dbcommon::BIGINT_ADD_BIGINT,
+ dbcommon::BIGINTID, countBuf, dbcommon::BIGINTID,
+ offsetBuf);
+ univPlanLimitAddLimitCount(univplan);
+ }
+
+ if (offset != -1) {
+ univPlanNewExpr(univplan);
+ univPlanExprAddConst(univplan, -1, dbcommon::BIGINTID, false, "0", -1);
+ univPlanLimitAddLimitOffset(univplan);
+ }
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+int32_t UnivPlanProtoUtility::constructLimitTop(int32_t pid, int64_t count,
+ int64_t offset) {
+ int32_t uid = univPlanLimitNewInstance(univplan, pid);
+
+ constructVarTargetEntry(-1, 1, 1, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 2, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+
+ univPlanSetPlanNodeInfo(univplan, static_cast<double>(count + offset), 0, 0);
+
+ if (count != -1) {
+ univPlanNewExpr(univplan);
+ std::string countTmp = std::to_string(count);
+ char const *countBuf = countTmp.c_str();
+ univPlanExprAddConst(univplan, -1, dbcommon::BIGINTID, false, countBuf, -1);
+ univPlanLimitAddLimitCount(univplan);
+ }
+
+ if (offset != -1) {
+ univPlanNewExpr(univplan);
+ std::string offsetTmp = std::to_string(offset);
+ char const *offsetBuf = offsetTmp.c_str();
+ univPlanExprAddConst(univplan, -1, dbcommon::BIGINTID, false, offsetBuf,
+ -1);
+ univPlanLimitAddLimitOffset(univplan);
+ }
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+int32_t UnivPlanProtoUtility::constructAgg(int32_t pid, int8_t aggstage) {
+ int32_t uid = univPlanAggNewInstance(univplan, pid);
+
+ constructAggRefTargetEntry(-1, aggstage, dbcommon::COUNT, 1, 1,
+ dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 2, dbcommon::TypeKind::INTID);
+ constructVarTargetEntry(-1, 1, 3, dbcommon::TypeKind::STRINGID);
+
+ int64_t numCols = 2;
+ int32_t *grpColIdx =
+ reinterpret_cast<int32_t *>(malloc(numCols * sizeof(int32_t)));
+ grpColIdx[0] = 1;
+ grpColIdx[1] = 3;
+ univPlanAggSetNumGroupsAndGroupColIndexes(univplan, 1000, numCols, grpColIdx);
+ free(grpColIdx);
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+int32_t UnivPlanProtoUtility::constructSort(int32_t pid) {
+ int32_t uid = univPlanSortNewInstance(univplan, pid);
+
+ int64_t numCols = 2;
+ int32_t *colIdx =
+ reinterpret_cast<int32_t *>(malloc(numCols * sizeof(int32_t)));
+ int32_t *mappingSortFuncId =
+ reinterpret_cast<int32_t *>(malloc(numCols * sizeof(int32_t)));
+ colIdx[0] = 1;
+ colIdx[1] = 2;
+ mappingSortFuncId[0] = dbcommon::BIGINT_LESS_THAN_BIGINT;
+ mappingSortFuncId[1] = dbcommon::INT_LESS_THAN_INT;
+ univPlanSortSetColIdx(univplan, numCols, colIdx);
+ univPlanSortSetSortFuncId(univplan, numCols, mappingSortFuncId);
+ free(colIdx);
+ free(mappingSortFuncId);
+
+ univPlanAddToPlanNode(univplan, true);
+ return uid;
+}
+
+void UnivPlanProtoUtility::constructRangeTable() {
+ univPlanRangeTblEntryAddDummy(univplan);
+
+ char location[] = "/tmp";
+ char fmtOptsJson[] = "option1 string in json";
+ int32_t columnNum = 2;
+ int32_t columnDataType[2] = {dbcommon::TypeKind::INTID,
+ dbcommon::TypeKind::STRINGID};
+ int64_t columnDataTypeMod[2] = {-1, -1};
+ std::string columnName_buf[2] = {"p1", "p2"};
+ std::unique_ptr<const char *[]> columnName(new const char *[2]);
+ columnName[0] = columnName_buf[0].c_str();
+ columnName[1] = columnName_buf[1].c_str();
+
+ univPlanRangeTblEntryAddTable(univplan, 2, UnivPlanOrcFormat, location,
+ fmtOptsJson, columnNum, columnName.get(),
+ columnDataType, columnDataTypeMod);
+}
+
+void UnivPlanProtoUtility::constructReceiver() {
+ std::string addr_buf1[1] = {"mdw"};
+ std::unique_ptr<const char *[]> addr1(new const char *[1]);
+ addr1[0] = addr_buf1[0].c_str();
+ int32_t port1[2] = {101};
+
+ std::string addr_buf2[2] = {"smdw", "smdw"};
+ std::unique_ptr<const char *[]> addr2(new const char *[2]);
+ addr2[0] = addr_buf2[0].c_str();
+ addr2[1] = addr_buf2[1].c_str();
+ int32_t port2[2] = {201, 203};
+
+ univPlanReceiverAddListeners(univplan, 1, addr1.get(), port1);
+ univPlanReceiverAddListeners(univplan, 2, addr2.get(), port2);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/testutil/univplan-proto-util.h b/depends/univplan/src/univplan/testutil/univplan-proto-util.h
new file mode 100644
index 0000000..4e63e30
--- /dev/null
+++ b/depends/univplan/src/univplan/testutil/univplan-proto-util.h
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_TESTUTIL_UNIVPLAN_PROTO_UTIL_H_
+#define UNIVPLAN_SRC_UNIVPLAN_TESTUTIL_UNIVPLAN_PROTO_UTIL_H_
+
+#include <string>
+#include <utility>
+
+#include "univplan/cwrapper/univplan-c.h"
+
+#include "dbcommon/log/logger.h"
+#include "dbcommon/type/type-kind.h"
+
+#include "univplan/common/stagize.h"
+#include "univplan/common/var-util.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-tree.h"
+#include "univplan/univplanbuilder/univplanbuilder-plan.h"
+#include "univplan/univplanbuilder/univplanbuilder-table.h"
+#include "univplan/univplanbuilder/univplanbuilder.h"
+
+struct UnivPlanC {
+ univplan::UnivPlanBuilder::uptr upb;
+ univplan::UnivPlanBuilderNode::uptr curNode;
+ univplan::UnivPlanBuilderExprTree::uptr curExpr;
+ std::string seriaizedPlan;
+ UnivPlanCatchedError error;
+ std::string debugString;
+ uint16_t totalStageNo;
+};
+
+typedef enum NodeTag {
+ T_Invalid = 0,
+ T_BoolExpr = 313,
+} NodeTag;
+
+typedef struct Expr {
+ NodeTag type;
+} Expr;
+
+typedef enum BoolExprType { AND_EXPR, OR_EXPR, NOT_EXPR } BoolExprType;
+
+struct ListCell {
+ union {
+ void *ptr_value;
+ int int_value;
+ unsigned int oid_value;
+ } data;
+ ListCell *next;
+};
+
+typedef struct List {
+ NodeTag type; /* T_List, T_IntList, or T_OidList */
+ int length;
+ ListCell *head;
+ ListCell *tail;
+} List;
+
+typedef struct BoolExpr {
+ Expr xpr;
+ BoolExprType boolop;
+ List *args; /* arguments to this expression */
+ int location; /* token location, or -1 if unknown */
+} BoolExpr;
+
+typedef enum NullTestType { IS_NULL, IS_NOT_NULL } NullTestType;
+
+typedef struct NullTest {
+ Expr xpr;
+ Expr *arg; /* input expression */
+ NullTestType nulltesttype; /* IS NULL, IS NOT NULL */
+} NullTest;
+
+namespace univplan {
+class UnivPlanProtoUtility {
+ public:
+ UnivPlanProtoUtility();
+ ~UnivPlanProtoUtility();
+
+ // like p op const
+ void constructVarOpConstExpr(int32_t pid, int32_t opFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType,
+ dbcommon::TypeKind constType,
+ const char *buffer);
+
+ // like const op p
+ void constructConstOpVarExpr(int32_t pid, int32_t opFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType,
+ dbcommon::TypeKind constType,
+ const char *buffer);
+ // like p op q
+ void constructVarOpVarExpr(int32_t pid, int32_t opFuncId, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2);
+
+ // like const op const
+ void constructConstOpConstExpr(int32_t pid, int32_t opFuncId,
+ dbcommon::TypeKind constType1,
+ const char *buffer1,
+ dbcommon::TypeKind constType2,
+ const char *buffer2);
+
+ // like func op p
+ void constructFuncOpVarExpr(int32_t pid, int32_t opFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType,
+ int32_t mappingFuncId);
+
+ // like p op const or q op const
+ void constructBoolExpr(int32_t pid, int32_t opFuncId1, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ dbcommon::TypeKind constType1, const char *buffer1,
+ int32_t opFuncId2, int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2,
+ dbcommon::TypeKind constType2, const char *buffer2,
+ int8_t boolType = 1);
+
+ // like p is (not) null
+ void constructNullTestExpr(int32_t pid, int8_t nulltesttype, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType);
+
+ // like (p op const) op (q op const)
+ void constructVarOpConstThenOpVarOpConstExpr(
+ int32_t pid, int32_t opFuncId, int32_t opFuncId1, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ dbcommon::TypeKind constType1, const char *buffer1, int32_t opFuncId2,
+ int32_t varNo2, int32_t varAttNo2, dbcommon::TypeKind varType2,
+ dbcommon::TypeKind constType2, const char *buffer2);
+
+ // TargetEntry with var
+ void constructVarTargetEntry(int32_t pid, int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind type);
+
+ // TargetEntry with const
+ void constructConstTargetEntry(int32_t pid, dbcommon::TypeKind constType,
+ const char *buffer);
+
+ // TargetEntry with const op const
+ void constructConstOpConstTargetEntry(int32_t pid, int32_t opFuncId,
+ dbcommon::TypeKind constType1,
+ const char *buffer1,
+ dbcommon::TypeKind constType2,
+ const char *buffer2);
+
+ // TargetEntry with Aggref
+ void constructAggRefTargetEntry(int32_t pid, int8_t aggstage, int32_t varNo,
+ int32_t mappingFuncId, int32_t varAttNo,
+ dbcommon::TypeKind type);
+
+ // TargetEntry with NullTest
+ void constructNullTestTargetEntry(int32_t pid, int8_t nulltesttype,
+ int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType);
+
+ // TargetEntry with p op const
+ void constructVarOpConstTargetEntry(int32_t pid, int32_t opFuncId,
+ int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType,
+ dbcommon::TypeKind constType,
+ const char *buffer);
+
+ // QualList like p op const
+ void constructVarOpConstQualList(int32_t pid, int32_t opFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType,
+ dbcommon::TypeKind constType,
+ const char *buffer);
+
+ // QualList like const op p
+ void constructConstOpVarQualList(int32_t pid, int32_t opFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType,
+ dbcommon::TypeKind constType,
+ const char *buffer);
+
+ // QualList like p op q
+ void constructVarOpVarQualList(int32_t pid, int32_t opFuncId, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ int32_t varNo2, int32_t varAttNo2,
+ dbcommon::TypeKind varType2);
+
+ // QualList like func op p
+ void constructFuncOpVarQualList(int32_t pid, int32_t opFuncId, int32_t varNo,
+ int32_t varAttNo, dbcommon::TypeKind varType,
+ int32_t mappingFuncId);
+
+ // QualList like p op const or q op const
+ void constructBoolQualList(int32_t pid, int32_t opFuncId1, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ dbcommon::TypeKind constType1, const char *buffer1,
+ int32_t opFuncId2, int32_t varNo2,
+ int32_t varAttNo2, dbcommon::TypeKind varType2,
+ dbcommon::TypeKind constType2, const char *buffer2,
+ int8_t boolType = 1);
+
+ // QualList with NullTest
+ void constructNullTestQualList(int32_t pid, int8_t nulltesttype,
+ int32_t varNo, int32_t varAttNo,
+ dbcommon::TypeKind varType);
+
+ // QualList like p op const or q op const
+ void constructVarOpConstThenOpVarOpConstQualList(
+ int32_t pid, int32_t opFuncId, int32_t opFuncId1, int32_t varNo1,
+ int32_t varAttNo1, dbcommon::TypeKind varType1,
+ dbcommon::TypeKind constType1, const char *buffer1, int32_t opFuncId2,
+ int32_t varNo2, int32_t varAttNo2, dbcommon::TypeKind varType2,
+ dbcommon::TypeKind constType2, const char *buffer2);
+
+ int32_t constructSeqScan(int32_t pid, bool wihQualList,
+ int8_t targetEntryType);
+
+ int32_t constructConnector(int32_t pid, int8_t ctype, bool allTargetEntry);
+
+ int32_t constructSortConnector(int32_t pid, int8_t ctype);
+
+ void constructRangeTable();
+
+ void constructReceiver();
+
+ // when count/limit = -1, means there is no count/limit
+ int32_t constructLimitBelow(int32_t pid, int64_t count, int64_t offset);
+
+ // when count/limit = -1, means there is no count/limit
+ int32_t constructLimitTop(int32_t pid, int64_t count, int64_t offset);
+
+ int32_t constructAgg(int32_t pid, int8_t aggstage);
+
+ int32_t constructSort(int32_t pid);
+
+ void univPlanFixVarType() { ::univPlanFixVarType(univplan); }
+
+ void univPlanStagize() { ::univPlanStagize(univplan); }
+
+ const char *univPlanSerialize(int32_t *size) {
+ return ::univPlanSerialize(univplan, size, true);
+ }
+
+ const char *univPlanGetJsonFormatedPlan() {
+ return ::univPlanGetJsonFormatedPlan(univplan);
+ }
+
+ void univPlanSetDoInstrument(bool doInstrument) {
+ ::univPlanSetDoInstrument(univplan, doInstrument);
+ }
+
+ int32_t univPlanSeqScanNewInstance(int32_t pid) {
+ return ::univPlanSeqScanNewInstance(univplan, pid);
+ }
+
+ void univPlanAddToPlanNodeTest(bool isleft) {
+ ::univPlanAddToPlanNode(univplan, isleft);
+ }
+
+ UnivPlanC *getUnivPlan() { return std::move(univplan); }
+
+ private:
+ UnivPlanC *univplan = nullptr;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_TESTUTIL_UNIVPLAN_PROTO_UTIL_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-agg.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-agg.cc
new file mode 100644
index 0000000..ea0e4bc
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-agg.cc
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-agg.h"
+
+namespace univplan {
+
+UnivPlanBuilderAgg::UnivPlanBuilderAgg() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanAgg());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderAgg::~UnivPlanBuilderAgg() {}
+
+UnivPlanBuilderPlanNodePoly::uptr UnivPlanBuilderAgg::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_AGG, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_agg(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderAgg::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_AGG);
+ ref->CopyFrom(node.agg());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderAgg::setNumGroups(int64_t n) { ref->set_numgroups(n); }
+
+void UnivPlanBuilderAgg::setGroupColIndexes(
+ const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_groupcolindexes(nArray[i]);
+ }
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-agg.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-agg.h
new file mode 100644
index 0000000..4434f40
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-agg.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_AGG_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_AGG_H_
+
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderAgg : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderAgg();
+ virtual ~UnivPlanBuilderAgg();
+
+ typedef std::unique_ptr<UnivPlanBuilderAgg> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setNumGroups(int64_t n);
+ void setGroupColIndexes(const std::vector<int32_t> &nArray);
+
+ private:
+ UnivPlanAgg *ref;
+ std::unique_ptr<UnivPlanAgg> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_AGG_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-append.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-append.cc
new file mode 100644
index 0000000..efe4aaf
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-append.cc
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-append.h"
+
+namespace univplan {
+
+UnivPlanBuilderAppend::UnivPlanBuilderAppend() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanAppend());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderAppend::~UnivPlanBuilderAppend() {}
+
+UnivPlanBuilderPlanNodePoly::uptr UnivPlanBuilderAppend::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_APPEND, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_append(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderAppend::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_APPEND);
+ ref->CopyFrom(node.append());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderAppend::addAppendPlan(const UnivPlanPlanNodePoly &node) {
+ UnivPlanPlanNodePoly *poly = ref->add_appendplans();
+ poly->CopyFrom(node);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-append.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-append.h
new file mode 100644
index 0000000..9642647
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-append.h
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_APPEND_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_APPEND_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderAppend : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderAppend();
+ virtual ~UnivPlanBuilderAppend();
+
+ typedef std::unique_ptr<UnivPlanBuilderAppend> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void addAppendPlan(const UnivPlanPlanNodePoly &node);
+
+ private:
+ UnivPlanAppend *ref;
+ std::unique_ptr<UnivPlanAppend> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_APPEND_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-column.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-column.h
new file mode 100644
index 0000000..0152e52
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-column.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_COLUMN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_COLUMN_H_
+
+#include <string>
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class UnivPlanBuilderColumn {
+ public:
+ explicit UnivPlanBuilderColumn(UnivPlanColumn *column) : ref(column) {}
+
+ virtual ~UnivPlanBuilderColumn() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderColumn> uptr;
+
+ void setColumnName(const std::string &columnName) {
+ ref->set_columnname(columnName);
+ }
+
+ void setTypeId(int32_t typeId) { ref->set_typeid_(typeId); }
+ void setTypeMod(int64_t typeMod) { ref->set_typemod(typeMod); }
+
+ void setScale1(int32_t scale) { ref->set_scale1(scale); }
+ void setScale2(int32_t scale) { ref->set_scale2(scale); }
+ void setIsNullable(bool nullable) { ref->set_isnullable(nullable); }
+
+ private:
+ UnivPlanColumn *ref = nullptr;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_COLUMN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-connector.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-connector.h
new file mode 100644
index 0000000..c48ae56
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-connector.h
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_CONNECTOR_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_CONNECTOR_H_
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderConnector : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderConnector() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanConnector);
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderConnector() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderConnector> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_CONNECTOR, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_connector(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_CONNECTOR);
+ ref->CopyFrom(node.connector());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ void setConnectorType(UNIVPLANCONNECTORTYPE type) { ref->set_type(type); }
+
+ void setStageNo(int stageNo) { ref->set_stageno(stageNo); }
+
+ void setMagmaTable(bool stageNo) { ref->set_magmatable(stageNo); }
+
+ void setMagmaMap(int *map) {
+ int rangeNum = ref->rangenum();
+ for (int i = 0; i < rangeNum; ++i) {
+ ref->add_magmamap(map[i]);
+ }
+ }
+
+ void setRangeNum(int rangeNum) { ref->set_rangenum(rangeNum); }
+
+ void setColIdx(const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_colidx(nArray[i]);
+ }
+ }
+
+ void setSortFuncId(const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_sortfuncid(nArray[i]);
+ }
+ }
+
+ void addHashExpr(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_hashexpr()->AddAllocated(exprTree->ownExprPoly().release());
+ }
+
+ private:
+ UnivPlanConnector *ref;
+ std::unique_ptr<UnivPlanConnector> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_CONNECTOR_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-node.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-node.h
new file mode 100644
index 0000000..8196919
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-node.h
@@ -0,0 +1,736 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_NODE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_NODE_H_
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-poly.h"
+
+namespace univplan {
+
+class UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderExprNode> uptr;
+
+ UnivPlanBuilderExprNode() {}
+
+ UnivPlanBuilderExprNode(int32_t pid, int32_t uid) : pid(pid), uid(uid) {}
+
+ virtual ~UnivPlanBuilderExprNode() {}
+
+ // Create a UnivPlanBuilderExprPoly instance and transfer out the ownership.
+ virtual std::unique_ptr<UnivPlanBuilderExprPoly> getExprPolyBuilder() = 0;
+
+ virtual UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) {
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR, "add args not implemented");
+ }
+
+ int32_t pid = -1;
+ int32_t uid = -1;
+};
+
+class UnivPlanBuilderVar final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderVar> uptr;
+
+ UnivPlanBuilderVar() : node_(new UnivPlanVar), ref_(node_.get()) {}
+
+ UnivPlanBuilderVar(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanVar),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_VAR));
+ exprPoly->getExprPoly()->set_allocated_var(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderVar &setVarNo(uint32_t varNo) {
+ ref_->set_varno(varNo);
+ return *this;
+ }
+
+ UnivPlanBuilderVar &setVarAttNo(int32_t varAttNo) {
+ ref_->set_varattno(varAttNo);
+ return *this;
+ }
+
+ UnivPlanBuilderVar &setTypeId(int32_t typeId) {
+ ref_->set_typeid_(typeId);
+ return *this;
+ }
+
+ UnivPlanBuilderVar &setTypeMod(int64_t typeMod) {
+ ref_->set_typemod(typeMod);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanVar> node_;
+ UnivPlanVar *ref_;
+};
+
+class UnivPlanBuilderConst final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderConst> uptr;
+
+ UnivPlanBuilderConst() : node_(new UnivPlanConst), ref_(node_.get()) {}
+
+ UnivPlanBuilderConst(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanConst),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_CONST));
+ exprPoly->getExprPoly()->set_allocated_val(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderConst &setType(int32_t type) {
+ ref_->set_type(type);
+ return *this;
+ }
+
+ UnivPlanBuilderConst &setTypeMod(int64_t typeMod) {
+ ref_->set_typemod(typeMod);
+ return *this;
+ }
+
+ UnivPlanBuilderConst &setIsNull(bool isNull) {
+ ref_->set_isnull(isNull);
+ return *this;
+ }
+
+ UnivPlanBuilderConst &setValue(const std::string &value) {
+ ref_->set_value(value);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanConst> node_;
+ UnivPlanConst *ref_;
+};
+
+class UnivPlanBuilderOpExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderOpExpr> uptr;
+
+ UnivPlanBuilderOpExpr() : node_(new UnivPlanOpExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderOpExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanOpExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_OPEXPR));
+ exprPoly->getExprPoly()->set_allocated_opexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ UnivPlanBuilderOpExpr &setRetType(int32_t retType) {
+ ref_->set_rettype(retType);
+ return *this;
+ }
+
+ UnivPlanBuilderOpExpr &setFuncId(int32_t funcId) {
+ ref_->set_funcid(funcId);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanOpExpr> node_;
+ UnivPlanOpExpr *ref_;
+};
+
+class UnivPlanBuilderFuncExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderFuncExpr> uptr;
+
+ UnivPlanBuilderFuncExpr() : node_(new UnivPlanFuncExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderFuncExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanFuncExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_FUNCEXPR));
+ exprPoly->getExprPoly()->set_allocated_funcexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderFuncExpr &setFuncId(int32_t funcId) {
+ ref_->set_funcid(funcId);
+ return *this;
+ }
+
+ UnivPlanBuilderFuncExpr &setRetType(int32_t retType) {
+ ref_->set_rettype(retType);
+ return *this;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanFuncExpr> node_;
+ UnivPlanFuncExpr *ref_;
+};
+
+class UnivPlanBuilderAggref final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderAggref> uptr;
+
+ UnivPlanBuilderAggref() : node_(new UnivPlanAggref), ref_(node_.get()) {}
+
+ UnivPlanBuilderAggref(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanAggref),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_AGGREF));
+ exprPoly->getExprPoly()->set_allocated_aggref(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderAggref &setFuncId(int32_t funcId) {
+ ref_->set_funcid(funcId);
+
+ return *this;
+ }
+
+ UnivPlanBuilderAggref &setTransFuncId(int32_t funcId) {
+ ref_->set_transfuncid(funcId);
+ return *this;
+ }
+
+ UnivPlanBuilderAggref &setFinalFuncId(int32_t funcId) {
+ ref_->set_finalfuncid(funcId);
+ return *this;
+ }
+
+ UnivPlanBuilderAggref &setRetType(int32_t retType) {
+ ref_->set_rettype(retType);
+ return *this;
+ }
+
+ UnivPlanBuilderAggref &setTransInitVal(bool transInitVal) {
+ ref_->set_transinitval(transInitVal);
+ return *this;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanAggref> node_;
+ UnivPlanAggref *ref_;
+};
+
+class UnivPlanBuilderBoolExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderBoolExpr> uptr;
+
+ UnivPlanBuilderBoolExpr() : node_(new UnivPlanBoolExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderBoolExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanBoolExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_BOOLEXPR));
+ exprPoly->getExprPoly()->set_allocated_boolexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderBoolExpr &setType(BOOLEXPRTYPE type) {
+ ref_->set_type(type);
+ return *this;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanBoolExpr> node_;
+ UnivPlanBoolExpr *ref_;
+};
+
+class UnivPlanBuilderNullTest final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderNullTest> uptr;
+
+ UnivPlanBuilderNullTest() : node_(new UnivPlanNullTest), ref_(node_.get()) {}
+
+ UnivPlanBuilderNullTest(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanNullTest),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_NULLTEST));
+ exprPoly->getExprPoly()->set_allocated_nulltest(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderNullTest &setType(NULLTESTTYPE type) {
+ ref_->set_type(type);
+ return *this;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->set_allocated_arg(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanNullTest> node_;
+ UnivPlanNullTest *ref_;
+};
+
+class UnivPlanBuilderBooleanTest final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderBooleanTest> uptr;
+
+ UnivPlanBuilderBooleanTest()
+ : node_(new UnivPlanBooleanTest), ref_(node_.get()) {}
+
+ UnivPlanBuilderBooleanTest(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanBooleanTest),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_BOOLEANTEST));
+ exprPoly->getExprPoly()->set_allocated_booltest(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderBooleanTest &setType(BOOLTESTTYPE type) {
+ ref_->set_type(type);
+ return *this;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->set_allocated_arg(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanBooleanTest> node_;
+ UnivPlanBooleanTest *ref_;
+};
+
+class UnivPlanBuilderCaseExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderCaseExpr> uptr;
+
+ UnivPlanBuilderCaseExpr() : node_(new UnivPlanCaseExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderCaseExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanCaseExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_CASEEXPR));
+ exprPoly->getExprPoly()->set_allocated_caseexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderCaseExpr &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ if (addingDefresult_) return setDefresult(std::move(arg));
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ UnivPlanBuilderCaseExpr &setCasetype(int32_t casetype) {
+ ref_->set_casetype(casetype);
+ return *this;
+ }
+
+ void setAddingDefresult() { addingDefresult_ = true; }
+
+ UnivPlanBuilderCaseExpr &setDefresult(UnivPlanBuilderExprPoly::uptr arg) {
+ ref_->set_allocated_defresult(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanCaseExpr> node_;
+ UnivPlanCaseExpr *ref_;
+ bool addingDefresult_ = false;
+};
+
+class UnivPlanBuilderCaseWhen final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderCaseWhen> uptr;
+
+ UnivPlanBuilderCaseWhen() : node_(new UnivPlanCaseWhen), ref_(node_.get()) {}
+
+ UnivPlanBuilderCaseWhen(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanCaseWhen),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_CASEWHEN));
+ exprPoly->getExprPoly()->set_allocated_casewhen(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderCaseWhen &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ if (addingResult_) return setResult(std::move(arg));
+ ref_->set_allocated_expr(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ void setAddingResult() { addingResult_ = true; }
+
+ UnivPlanBuilderCaseWhen &setResult(UnivPlanBuilderExprPoly::uptr arg) {
+ ref_->set_allocated_result(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanCaseWhen> node_;
+ UnivPlanCaseWhen *ref_;
+ bool addingResult_ = false;
+};
+
+class UnivPlanBuilderSubPlan final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderSubPlan> uptr;
+
+ UnivPlanBuilderSubPlan() : node_(new UnivPlanSubPlan), ref_(node_.get()) {}
+
+ UnivPlanBuilderSubPlan(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanSubPlan),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_SUBPLAN));
+ exprPoly->getExprPoly()->set_allocated_subplan(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderSubPlan &setSubLinkType(SUBLINKTYPE subLinkType) {
+ ref_->set_sublinktype(subLinkType);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &setPlanId(int32_t planId) {
+ ref_->set_planid(planId);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &setTypeId(int32_t typeId) {
+ ref_->set_typeid_(typeId);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &setTypeMod(int64_t typeMod) {
+ ref_->set_typemod(typeMod);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &setUseHashTable(bool useHashTable) {
+ ref_->set_usehashtable(useHashTable);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &setInitPlan(bool initPlan) {
+ ref_->set_initplan(initPlan);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &addSetParam(int32_t setParam) {
+ ref_->add_setparam(setParam);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &addParParam(int32_t parParam) {
+ ref_->add_parentparam(parParam);
+ return *this;
+ }
+
+ UnivPlanBuilderSubPlan &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ if (addingTestexpr_) {
+ ref_->set_allocated_testexpr(arg->ownExprPoly().release());
+ } else {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ }
+ return *this;
+ }
+
+ void setAddingTestexpr() { addingTestexpr_ = true; }
+
+ UnivPlanBuilderSubPlan &addTestexprParam(int32_t testexprParam) {
+ ref_->add_testexprparam(testexprParam);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanSubPlan> node_;
+ UnivPlanSubPlan *ref_;
+ bool addingTestexpr_ = false;
+};
+
+class UnivPlanBuilderParam final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderParam> uptr;
+
+ UnivPlanBuilderParam() : node_(new UnivPlanParam), ref_(node_.get()) {}
+
+ UnivPlanBuilderParam(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanParam),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_PARAM));
+ exprPoly->getExprPoly()->set_allocated_param(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderParam &setParamKind(PARAMKIND paramKind) {
+ ref_->set_paramkind(paramKind);
+ return *this;
+ }
+
+ UnivPlanBuilderParam &setParamId(int32_t paramId) {
+ ref_->set_paramid(paramId);
+ return *this;
+ }
+
+ UnivPlanBuilderParam &setTypeId(int32_t typeId) {
+ ref_->set_typeid_(typeId);
+ return *this;
+ }
+
+ UnivPlanBuilderParam &setTypeMod(int64_t typeMod) {
+ ref_->set_typemod(typeMod);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanParam> node_;
+ UnivPlanParam *ref_;
+};
+
+class UnivPlanBuilderScalarArrayOpExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderOpExpr> uptr;
+
+ UnivPlanBuilderScalarArrayOpExpr()
+ : node_(new UnivPlanScalarArrayOpExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderScalarArrayOpExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanScalarArrayOpExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_SCALARARRAYOPEXPR));
+ exprPoly->getExprPoly()->set_allocated_scalararrayopexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ UnivPlanBuilderScalarArrayOpExpr &setUseOr(bool useOr) {
+ ref_->set_useor(useOr);
+ return *this;
+ }
+
+ UnivPlanBuilderScalarArrayOpExpr &setFuncId(int32_t funcId) {
+ ref_->set_funcid(funcId);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanScalarArrayOpExpr> node_;
+ UnivPlanScalarArrayOpExpr *ref_;
+};
+
+class UnivPlanBuilderCoalesceExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderCoalesceExpr> uptr;
+
+ UnivPlanBuilderCoalesceExpr()
+ : node_(new UnivPlanCoalesceExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderCoalesceExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanCoalesceExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_COALESCEEXPR));
+ exprPoly->getExprPoly()->set_allocated_coalesceexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderCoalesceExpr &addArgs(
+ UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ UnivPlanBuilderCoalesceExpr &setCoalesceType(int32_t coalesceType) {
+ ref_->set_coalescetype(coalesceType);
+ return *this;
+ }
+
+ UnivPlanBuilderCoalesceExpr &setCoalesceTypeMod(int32_t coalesceTypeMod) {
+ ref_->set_coalescetypemod(coalesceTypeMod);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanCoalesceExpr> node_;
+ UnivPlanCoalesceExpr *ref_;
+};
+
+class UnivPlanBuilderNullIfExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderNullIfExpr> uptr;
+
+ UnivPlanBuilderNullIfExpr()
+ : node_(new UnivPlanNullIfExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderNullIfExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanNullIfExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_NULLIFEXPR));
+ exprPoly->getExprPoly()->set_allocated_nullifexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderNullIfExpr &addArgs(
+ UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ UnivPlanBuilderNullIfExpr &setRetType(int32_t retType) {
+ ref_->set_rettype(retType);
+ return *this;
+ }
+
+ UnivPlanBuilderNullIfExpr &setTypeMod(int32_t typeMod) {
+ ref_->set_typemod(typeMod);
+ return *this;
+ }
+
+ UnivPlanBuilderNullIfExpr &setFuncId(int32_t funcId) {
+ ref_->set_funcid(funcId);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanNullIfExpr> node_;
+ UnivPlanNullIfExpr *ref_;
+};
+
+class UnivPlanBuilderDistinctExpr final : public UnivPlanBuilderExprNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderDistinctExpr> uptr;
+
+ UnivPlanBuilderDistinctExpr()
+ : node_(new UnivPlanDistinctExpr), ref_(node_.get()) {}
+
+ UnivPlanBuilderDistinctExpr(int32_t pid, int32_t uid)
+ : UnivPlanBuilderExprNode(pid, uid),
+ node_(new UnivPlanDistinctExpr),
+ ref_(node_.get()) {}
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() override {
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_DISTINCTEXPR));
+ exprPoly->getExprPoly()->set_allocated_distinctexpr(node_.release());
+ return exprPoly;
+ }
+
+ UnivPlanBuilderExprNode &addArgs(UnivPlanBuilderExprPoly::uptr arg) override {
+ ref_->mutable_args()->AddAllocated(arg->ownExprPoly().release());
+ return *this;
+ }
+
+ UnivPlanBuilderDistinctExpr &setRetType(int32_t retType) {
+ ref_->set_rettype(retType);
+ return *this;
+ }
+
+ UnivPlanBuilderDistinctExpr &setFuncId(int32_t funcId) {
+ ref_->set_funcid(funcId);
+ return *this;
+ }
+
+ private:
+ std::unique_ptr<UnivPlanDistinctExpr> node_;
+ UnivPlanDistinctExpr *ref_;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_NODE_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-poly.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-poly.h
new file mode 100644
index 0000000..f783dc8
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-poly.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_POLY_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_POLY_H_
+
+#include "dbcommon/log/logger.h"
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class UnivPlanBuilderExprPoly {
+ public:
+ explicit UnivPlanBuilderExprPoly(UNIVPLANEXPRTYPE type) {
+ exprPoly.reset(new UnivPlanExprPoly());
+ ref = exprPoly.get();
+ ref->set_type(type);
+ }
+
+ virtual ~UnivPlanBuilderExprPoly() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderExprPoly> uptr;
+
+ UnivPlanExprPoly *getExprPoly() { return ref; }
+
+ std::unique_ptr<UnivPlanExprPoly> ownExprPoly() {
+ return std::move(exprPoly);
+ }
+
+ private:
+ UnivPlanExprPoly *ref;
+ std::unique_ptr<UnivPlanExprPoly> exprPoly;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_POLY_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-tree.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-tree.h
new file mode 100644
index 0000000..9c59186
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-expr-tree.h
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_TREE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_TREE_H_
+
+#include <map>
+#include <memory>
+#include <utility>
+
+#include "univplan/common/univplan-type.h"
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-node.h"
+
+namespace univplan {
+class UnivPlanBuilderExprTree {
+ public:
+ UnivPlanBuilderExprTree() {}
+ typedef std::unique_ptr<UnivPlanBuilderExprTree> uptr;
+
+ std::unique_ptr<UnivPlanExprPoly> ownExprPoly() { return std::move(root); }
+ void setRoot(UnivPlanBuilderExprPoly::uptr exprPoly) {
+ root = std::move(exprPoly->ownExprPoly());
+ }
+
+ int32_t getUid() { return nodeCounter++; }
+
+ // Create a new UnivPlanBuilderExprNode
+ // @param pid Parent ID for the new UnivPlanBuilderExprNode
+ template <typename UnivPlanBuilderExprNode>
+ std::unique_ptr<UnivPlanBuilderExprNode> ExprNodeFactory(int32_t pid) {
+ return std::unique_ptr<UnivPlanBuilderExprNode>(
+ new UnivPlanBuilderExprNode(pid, getUid()));
+ }
+
+ void addExprNode(UnivPlanBuilderExprNode::uptr bld) {
+ UnivPlanBuilderExprPoly::uptr pn = bld->getExprPolyBuilder();
+ int32_t uid = bld->uid; // required field
+ int32_t pid = bld->pid; // required field
+
+ // Check if this node has node id set already
+ if (uid < 0)
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "UnivPlanBuilderExprTree::addExprNode uid is negative");
+
+ // Check if the id is unique
+ if (idToExprNode.find(uid) != idToExprNode.end())
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "UnivPlanBuilderExprTree::addExprNode uid is duplicate");
+
+ // Use hash table to track this node quickly
+ idToExprNode[uid] = std::move(bld);
+
+ if (pid < 0) {
+ // If this node has no parent id, that means this node is a root, it is
+ // not allowed to have more than one root plan node.
+
+ // Set as a root plan node
+ setRoot(std::move(pn));
+
+ } else {
+ // If this node has a parent id, that means this node should be connected
+ // to its expected parent node.
+
+ // Find its parent node if its parent id is specified
+ if (idToExprNode.find(pid) == idToExprNode.end())
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "UnivPlanBuilderExprTree::addExprNode unexpected parent id "
+ "%d found",
+ pid);
+
+ // add to parent node
+ idToExprNode[pid]->addArgs(std::move(pn));
+ }
+ }
+
+ UnivPlanBuilderExprNode* getExprNode(int32_t uid) {
+ return idToExprNode[uid].get();
+ }
+
+ private:
+ std::unique_ptr<UnivPlanExprPoly> root = nullptr;
+ std::map<int32_t, UnivPlanBuilderExprNode::uptr> idToExprNode;
+ int32_t nodeCounter = 0;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXPR_TREE_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-filter.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-filter.cc
new file mode 100644
index 0000000..734be3f
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-filter.cc
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-ext-gs-filter.h"
+
+namespace univplan {
+
+UnivPlanBuilderExtGSFilter::UnivPlanBuilderExtGSFilter()
+ : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanExtGSFilter());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderExtGSFilter::~UnivPlanBuilderExtGSFilter() {}
+
+void UnivPlanBuilderExtGSFilter::setExpr(
+ UnivPlanBuilderExprPoly::uptr exprPoly) {
+ ref->set_allocated_filter(exprPoly->ownExprPoly().release());
+}
+
+std::unique_ptr<UnivPlanBuilderPlanNodePoly>
+UnivPlanBuilderExtGSFilter::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(new UnivPlanBuilderPlanNodePoly(
+ UNIVPLAN_EXT_GS_FILTER, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_extgsfilter(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderExtGSFilter::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_EXT_GS_FILTER);
+ ref->CopyFrom(node.extgsfilter());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-filter.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-filter.h
new file mode 100644
index 0000000..63442ea
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-filter.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_FILTER_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_FILTER_H_
+
+#include <memory>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderExtGSFilter : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderExtGSFilter();
+ virtual ~UnivPlanBuilderExtGSFilter();
+
+ typedef std::unique_ptr<UnivPlanBuilderExtGSFilter> uptr;
+
+ std::unique_ptr<UnivPlanBuilderPlanNodePoly> ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setExpr(UnivPlanBuilderExprPoly::uptr exprPoly);
+
+ private:
+ UnivPlanExtGSFilter *ref;
+ std::unique_ptr<UnivPlanExtGSFilter> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_FILTER_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-proj.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-proj.cc
new file mode 100644
index 0000000..95baa59
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-proj.cc
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-ext-gs-proj.h"
+
+namespace univplan {
+
+UnivPlanBuilderExtGSProject::UnivPlanBuilderExtGSProject()
+ : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanExtGSProj());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderExtGSProject::~UnivPlanBuilderExtGSProject() {}
+
+void UnivPlanBuilderExtGSProject::setColumnIndexes(
+ const std::vector<int32_t> &colIndexes) {
+ for (int i = 0; i < colIndexes.size(); ++i) {
+ ref->add_columnindexes(colIndexes[i]);
+ }
+}
+
+std::unique_ptr<UnivPlanBuilderPlanNodePoly>
+UnivPlanBuilderExtGSProject::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_EXT_GS_PROJ, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_extgsproject(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderExtGSProject::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_EXT_GS_PROJ);
+ ref->CopyFrom(node.extgsproject());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-proj.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-proj.h
new file mode 100644
index 0000000..4d7fb31
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-proj.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_PROJ_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_PROJ_H_
+
+#include <memory>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderExtGSProject : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderExtGSProject();
+ virtual ~UnivPlanBuilderExtGSProject();
+
+ typedef std::unique_ptr<UnivPlanBuilderExtGSProject> uptr;
+
+ std::unique_ptr<UnivPlanBuilderPlanNodePoly> ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setColumnIndexes(const std::vector<int32_t> &colIndexes);
+
+ private:
+ UnivPlanExtGSProj *ref;
+ std::unique_ptr<UnivPlanExtGSProj> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_PROJ_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-scan.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-scan.cc
new file mode 100644
index 0000000..1352fd5
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-scan.cc
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-ext-gs-scan.h"
+
+#include <utility>
+#include <vector>
+
+namespace univplan {
+
+UnivPlanBuilderExtGSScan::UnivPlanBuilderExtGSScan() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanExtGSScan());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderExtGSScan::~UnivPlanBuilderExtGSScan() {}
+
+std::unique_ptr<UnivPlanBuilderPlanNodePoly>
+UnivPlanBuilderExtGSScan::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_EXT_GS_SCAN, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_extgsscan(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderExtGSScan::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_EXT_GS_SCAN);
+ ref->CopyFrom(node.extgsscan());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderExtGSScan::setScanRelId(uint32_t id) { ref->set_relid(id); }
+
+void UnivPlanBuilderExtGSScan::setScanIndex(bool index = false) {
+ ref->set_indexscan(index);
+}
+
+void UnivPlanBuilderExtGSScan::setIndexScanType(ExternalScanType type) {
+ ref->set_type(univplan::ExternalScanType(type));
+}
+
+void UnivPlanBuilderExtGSScan::setDirectionType(
+ ExternalScanDirection direction) {
+ ref->set_direction(univplan::ExternalScanDirection(direction));
+}
+
+void UnivPlanBuilderExtGSScan::setIndexName(const char *indexName) {
+ ref->set_indexname(indexName);
+}
+
+void UnivPlanBuilderExtGSScan::addIndexQual(
+ UnivPlanBuilderExprTree::uptr exprTree) {
+ ref->mutable_indexqual()->AddAllocated(exprTree->ownExprPoly().release());
+}
+
+void UnivPlanBuilderExtGSScan::setColumnsToRead(
+ const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_columnstoread(nArray[i]);
+ }
+}
+
+void UnivPlanBuilderExtGSScan::setKeyColumnIndexes(
+ const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_keycolindex(nArray[i]);
+ }
+}
+
+void UnivPlanBuilderExtGSScan::setFilterExpr(
+ UnivPlanBuilderExprTree::uptr expr) {
+ ref->set_allocated_filter(expr->ownExprPoly().release());
+}
+
+std::unique_ptr<UnivPlanBuilderScanTask>
+UnivPlanBuilderExtGSScan::addScanTaskAndGetBuilder() {
+ UnivPlanScanTask *task = ref->add_tasks();
+ std::unique_ptr<UnivPlanBuilderScanTask> res(
+ new UnivPlanBuilderScanTask(task));
+ return std::move(res);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-scan.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-scan.h
new file mode 100644
index 0000000..5a3c54d
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-ext-gs-scan.h
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_SCAN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_SCAN_H_
+
+#include <memory>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+#include "univplan/univplanbuilder/univplanbuilder-scan-task.h"
+
+namespace univplan {
+
+class UnivPlanBuilderExtGSScan : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderExtGSScan();
+ virtual ~UnivPlanBuilderExtGSScan();
+
+ typedef std::unique_ptr<UnivPlanBuilderExtGSScan> uptr;
+
+ std::unique_ptr<UnivPlanBuilderPlanNodePoly> ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setScanRelId(uint32_t id);
+ void setColumnsToRead(const std::vector<int32_t> &nArray);
+ void setKeyColumnIndexes(const std::vector<int32_t> &nArray);
+ void setFilterExpr(UnivPlanBuilderExprTree::uptr expr);
+ std::unique_ptr<UnivPlanBuilderScanTask> addScanTaskAndGetBuilder();
+ // set magma index info
+ void setScanIndex(bool index);
+ void setIndexScanType(ExternalScanType type);
+ void setDirectionType(ExternalScanDirection direction);
+ void setIndexName(const char *indexName);
+ void addIndexQual(UnivPlanBuilderExprTree::uptr exprTree);
+
+ private:
+ UnivPlanExtGSScan *ref;
+ std::unique_ptr<UnivPlanExtGSScan> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_EXT_GS_SCAN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-hash.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-hash.h
new file mode 100644
index 0000000..05acb59
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-hash.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_HASH_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_HASH_H_
+
+#include <memory>
+#include <utility>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderHash : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderHash() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanHash());
+ ref = planNode.get();
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderHash() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderHash> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_HASH, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_hash(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_HASH);
+ ref->CopyFrom(node.hash());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ private:
+ UnivPlanHash *ref;
+ std::unique_ptr<UnivPlanHash> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_HASH_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-hashjoin.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-hashjoin.h
new file mode 100644
index 0000000..a0d51f1
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-hashjoin.h
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_HASHJOIN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_HASHJOIN_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderHashJoin : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderHashJoin() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanHashJoin());
+ ref = planNode.get();
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderHashJoin() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderHashJoin> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_HASHJOIN, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_hashjoin(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_HASHJOIN);
+ ref->CopyFrom(node.hashjoin());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ void addJoinQual(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_joinqual()->AddAllocated(exprTree->ownExprPoly().release());
+ }
+
+ void addHashClause(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_hashclauses()->AddAllocated(exprTree->ownExprPoly().release());
+ }
+
+ void addHashQualClause(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_hashqualclauses()->AddAllocated(
+ exprTree->ownExprPoly().release());
+ }
+
+ void setJoinType(UNIVPLANJOINTYPE type) { ref->set_type(type); }
+
+ private:
+ UnivPlanHashJoin *ref;
+ std::unique_ptr<UnivPlanHashJoin> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_HASHJOIN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-insert.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-insert.cc
new file mode 100644
index 0000000..a43aba8
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-insert.cc
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-insert.h"
+
+namespace univplan {
+
+UnivPlanBuilderInsert::UnivPlanBuilderInsert() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanInsert());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderInsert::~UnivPlanBuilderInsert() {}
+
+UnivPlanBuilderPlanNodePoly::uptr UnivPlanBuilderInsert::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_INSERT, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_insert(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderInsert::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_INSERT);
+ ref->CopyFrom(node.insert());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderInsert::setInsertRelId(uint32_t id) { ref->set_relid(id); }
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-insert.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-insert.h
new file mode 100644
index 0000000..910891a
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-insert.h
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_INSERT_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_INSERT_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderInsert : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderInsert();
+ virtual ~UnivPlanBuilderInsert();
+
+ typedef std::unique_ptr<UnivPlanBuilderInsert> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setInsertRelId(uint32_t id);
+
+ private:
+ UnivPlanInsert *ref;
+ std::unique_ptr<UnivPlanInsert> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_INSERT_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-limit.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-limit.cc
new file mode 100644
index 0000000..d65c119
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-limit.cc
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-limit.h"
+
+namespace univplan {
+
+UnivPlanBuilderLimit::UnivPlanBuilderLimit() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanLimit());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderLimit::~UnivPlanBuilderLimit() {}
+
+UnivPlanBuilderPlanNodePoly::uptr UnivPlanBuilderLimit::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_LIMIT, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_limit(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderLimit::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_LIMIT);
+ ref->CopyFrom(node.limit());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderLimit::setLimitOffset(
+ UnivPlanBuilderExprTree::uptr offset) {
+ ref->set_allocated_limitoffset(offset->ownExprPoly().release());
+}
+
+void UnivPlanBuilderLimit::setLimitCount(UnivPlanBuilderExprTree::uptr count) {
+ ref->set_allocated_limitcount(count->ownExprPoly().release());
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-limit.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-limit.h
new file mode 100644
index 0000000..0f61f54
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-limit.h
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_LIMIT_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_LIMIT_H_
+
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderLimit : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderLimit();
+ virtual ~UnivPlanBuilderLimit();
+
+ typedef std::unique_ptr<UnivPlanBuilderLimit> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setLimitOffset(UnivPlanBuilderExprTree::uptr limitOffset);
+
+ void setLimitCount(UnivPlanBuilderExprTree::uptr limitCount);
+
+ private:
+ UnivPlanLimit *ref;
+ std::unique_ptr<UnivPlanLimit> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_LIMIT_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-listener.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-listener.h
new file mode 100644
index 0000000..ae8be2a
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-listener.h
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_LISTENER_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_LISTENER_H_
+
+#include <string>
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class UnivPlanBuilderListener {
+ public:
+ explicit UnivPlanBuilderListener(UnivPlanListener *listener)
+ : ref(listener) {}
+
+ virtual ~UnivPlanBuilderListener() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderListener> uptr;
+
+ void setAddress(const std::string &addr) { ref->set_address(addr); }
+
+ void setPort(int32_t port) { ref->set_port(port); }
+
+ private:
+ UnivPlanListener *ref;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_LISTENER_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-material.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-material.h
new file mode 100644
index 0000000..bdb1dd2
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-material.h
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_MATERIAL_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_MATERIAL_H_
+
+#include <memory>
+#include <utility>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderMaterial : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderMaterial() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanMaterial());
+ ref = planNode.get();
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderMaterial() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderMaterial> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_MATERIAL, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_material(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly& node) override {
+ assert(node.type() == UNIVPLAN_MATERIAL);
+ ref->CopyFrom(node.material());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ UnivPlanBuilderMaterial& setShareType(UNIVPLANSHARETYPE type) {
+ ref->set_share_type(type);
+ return *this;
+ }
+
+ UnivPlanBuilderMaterial& setCdbStrict(bool cdbStrict) {
+ ref->set_cdbstrict(cdbStrict);
+ return *this;
+ }
+
+ UnivPlanBuilderMaterial& setShareId(int32_t shareId) {
+ ref->set_shared_id(shareId);
+ return *this;
+ }
+
+ UnivPlanBuilderMaterial& setDriverSlice(int32_t driverSlice) {
+ ref->set_driver_slice(driverSlice);
+ return *this;
+ }
+
+ UnivPlanBuilderMaterial& setNSharer(int32_t nsharer) {
+ ref->set_nsharer(nsharer);
+ return *this;
+ }
+
+ UnivPlanBuilderMaterial& setNSharerXSlice(int32_t xslice) {
+ ref->set_nsharer_xslice(xslice);
+ return *this;
+ }
+
+ private:
+ UnivPlanMaterial* ref;
+ std::unique_ptr<UnivPlanMaterial> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_MATERIAL_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-mergejoin.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-mergejoin.h
new file mode 100644
index 0000000..824e2de
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-mergejoin.h
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_MERGEJOIN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_MERGEJOIN_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderMergeJoin : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderMergeJoin() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanMergeJoin());
+ ref = planNode.get();
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderMergeJoin() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderMergeJoin> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_MERGEJOIN, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_mergejoin(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_MERGEJOIN);
+ ref->CopyFrom(node.mergejoin());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ void addJoinQual(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_joinqual()->AddAllocated(exprTree->ownExprPoly().release());
+ }
+
+ void addMergeClause(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_mergeclauses()->AddAllocated(
+ exprTree->ownExprPoly().release());
+ }
+
+ void setJoinType(UNIVPLANJOINTYPE type) { ref->set_type(type); }
+
+ private:
+ UnivPlanMergeJoin *ref;
+ std::unique_ptr<UnivPlanMergeJoin> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_MERGEJOIN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-nestloop.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-nestloop.h
new file mode 100644
index 0000000..193ce75
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-nestloop.h
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_NESTLOOP_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_NESTLOOP_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderNestLoop : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderNestLoop() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanNestLoop());
+ ref = planNode.get();
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderNestLoop() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderNestLoop> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_NESTLOOP, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_nestloop(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_NESTLOOP);
+ ref->CopyFrom(node.nestloop());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ void addJoinQual(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_joinqual()->AddAllocated(exprTree->ownExprPoly().release());
+ }
+
+ void setJoinType(UNIVPLANJOINTYPE type) { ref->set_type(type); }
+
+ private:
+ UnivPlanNestLoop *ref;
+ std::unique_ptr<UnivPlanNestLoop> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_NESTLOOP_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-node.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-node.cc
new file mode 100644
index 0000000..cd86ff5
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-node.cc
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+#include <utility>
+
+namespace univplan {
+
+void UnivPlanBuilderNode::setNodeLeftPlan(
+ UnivPlanBuilderPlanNodePoly::uptr pn) {
+ assert(baseRef != nullptr);
+ baseRef->set_allocated_leftplan(pn->ownPlanNodePoly().release());
+}
+
+void UnivPlanBuilderNode::setNodeRightPlan(
+ UnivPlanBuilderPlanNodePoly::uptr pn) {
+ assert(baseRef != nullptr);
+ baseRef->set_allocated_rightplan(pn->ownPlanNodePoly().release());
+}
+
+void UnivPlanBuilderNode::setNodePlanRows(double planRows) {
+ assert(baseRef != nullptr);
+ baseRef->set_planrows(planRows);
+}
+
+void UnivPlanBuilderNode::setNodePlanRowWidth(int32_t planRowWidth) {
+ assert(baseRef != nullptr);
+ baseRef->set_planrowwidth(planRowWidth);
+}
+
+void UnivPlanBuilderNode::setNodePlanOperatorMemKB(uint64_t operatorMemKB) {
+ baseRef->set_operatormemkb(operatorMemKB);
+}
+
+UnivPlanBuilderTargetEntry::uptr
+UnivPlanBuilderNode::addTargetEntryAndGetBuilder() {
+ assert(baseRef != nullptr);
+ UnivPlanExprPoly *exprTree = baseRef->add_targetlist();
+ exprTree->set_type(UNIVPLAN_EXPR_TARGETENTRY);
+ UnivPlanTargetEntry *targetEntry = exprTree->mutable_targetentry();
+ UnivPlanBuilderTargetEntry::uptr bld(
+ new UnivPlanBuilderTargetEntry(targetEntry));
+ return std::move(bld);
+}
+
+void UnivPlanBuilderNode::addQualList(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(baseRef != nullptr);
+ baseRef->mutable_quallist()->AddAllocated(exprTree->ownExprPoly().release());
+}
+
+void UnivPlanBuilderNode::addInitplan(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(baseRef != nullptr);
+ baseRef->mutable_initplan()->AddAllocated(exprTree->ownExprPoly().release());
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-node.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-node.h
new file mode 100644
index 0000000..437f7d0
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-node.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_NODE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_NODE_H_
+
+#include <memory>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-tree.h"
+#include "univplan/univplanbuilder/univplanbuilder-plan-node-poly.h"
+#include "univplan/univplanbuilder/univplanbuilder-target-entry.h"
+
+namespace univplan {
+
+class UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderNode() {
+ basePlanNode.reset(new UnivPlanPlanNode());
+ baseRef = basePlanNode.get();
+ }
+ virtual ~UnivPlanBuilderNode() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderNode> uptr;
+
+ void setNodeLeftPlan(UnivPlanBuilderPlanNodePoly::uptr pn);
+ void setNodeRightPlan(UnivPlanBuilderPlanNodePoly::uptr pn);
+
+ void setNodePlanRows(double planRows);
+
+ void setNodePlanRowWidth(int32_t planRowWidth);
+
+ void setNodePlanOperatorMemKB(uint64_t operatorMemKB);
+
+ virtual std::unique_ptr<UnivPlanBuilderPlanNodePoly> ownPlanNode() = 0;
+
+ // copy from the plannode content without left and right child
+ virtual void from(const UnivPlanPlanNodePoly &node) = 0;
+
+ UnivPlanBuilderTargetEntry::uptr addTargetEntryAndGetBuilder();
+ void addQualList(UnivPlanBuilderExprTree::uptr exprTree);
+ void addInitplan(UnivPlanBuilderExprTree::uptr exprTree);
+
+ public:
+ int32_t uid = -1;
+ int32_t pid = -1;
+
+ protected:
+ std::unique_ptr<UnivPlanPlanNode> basePlanNode;
+ UnivPlanPlanNode *baseRef = nullptr;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_NODE_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-paraminfo.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-paraminfo.h
new file mode 100644
index 0000000..99900c3
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-paraminfo.h
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PARAMINFO_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PARAMINFO_H_
+
+#include <string>
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class UnivPlanBuilderParamInfo {
+ public:
+ explicit UnivPlanBuilderParamInfo(UnivPlanParamInfo *paramInfo)
+ : ref_(paramInfo) {}
+
+ virtual ~UnivPlanBuilderParamInfo() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderParamInfo> uptr;
+
+ UnivPlanBuilderParamInfo &setType(int32_t type) {
+ ref_->set_type(type);
+ return *this;
+ }
+
+ UnivPlanBuilderParamInfo &setIsNull(bool isNull) {
+ ref_->set_isnull(isNull);
+ return *this;
+ }
+
+ UnivPlanBuilderParamInfo &setValue(const std::string &value) {
+ ref_->set_value(value);
+ return *this;
+ }
+
+ private:
+ UnivPlanParamInfo *ref_;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PARAMINFO_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan-node-poly.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan-node-poly.h
new file mode 100644
index 0000000..7d83518
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan-node-poly.h
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PLAN_NODE_POLY_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PLAN_NODE_POLY_H_
+
+#include <memory>
+#include <utility>
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class UnivPlanBuilderPlanNodePoly {
+ public:
+ UnivPlanBuilderPlanNodePoly(UNIVPLANNODETYPE type,
+ const UnivPlanPlanNode &planNode)
+ : planNode(planNode) {
+ pn.reset(new UnivPlanPlanNodePoly());
+ ref = pn.get();
+ ref->set_type(type);
+ }
+
+ virtual ~UnivPlanBuilderPlanNodePoly() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderPlanNodePoly> uptr;
+
+ UnivPlanPlanNodePoly *getPlanNodePoly() { return ref; }
+
+ std::unique_ptr<UnivPlanPlanNodePoly> ownPlanNodePoly() {
+ return std::move(pn);
+ }
+
+ const UnivPlanPlanNode &getPlanNode() { return planNode; }
+
+ private:
+ UnivPlanPlanNodePoly *ref;
+ std::unique_ptr<UnivPlanPlanNodePoly> pn;
+ const UnivPlanPlanNode &planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PLAN_NODE_POLY_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan.cc
new file mode 100644
index 0000000..3d9e75e
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan.cc
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-plan.h"
+
+#include <utility>
+
+#include "dbcommon/log/logger.h"
+#include "univplan/univplanbuilder/univplanbuilder-plan-node-poly.h"
+
+namespace univplan {
+
+void UnivPlanBuilderPlan::setPlanNode(UnivPlanBuilderPlanNodePoly::uptr pn) {
+ ref->set_allocated_plan(pn->ownPlanNodePoly().release());
+}
+
+void UnivPlanBuilderPlan::setSubplanNode(UnivPlanBuilderPlanNodePoly::uptr pn) {
+ ref->mutable_subplans()->AddAllocated(pn->ownPlanNodePoly().release());
+}
+
+void UnivPlanBuilderPlan::setStageNo(int32_t stageNo) {
+ ref->set_stageno(stageNo);
+}
+
+void UnivPlanBuilderPlan::setTokenEntry(std::string protocol, std::string host,
+ int port, std::string token) {
+ UnivPlanTokenEntry *tokenEntry = ref->add_tokenmap();
+ tokenEntry->set_token(token);
+ auto key = tokenEntry->mutable_key();
+ key->set_protocol(protocol);
+ key->set_ip(host);
+ key->set_port(port);
+}
+
+void UnivPlanBuilderPlan::setSnapshot(const std::string &snapshot) {
+ ref->set_snapshot(snapshot);
+}
+
+void UnivPlanBuilderPlan::addGuc(const std::string &name,
+ const std::string &value) {
+ (*ref->mutable_guc())[name] = value;
+}
+
+void UnivPlanBuilderPlan::addCommonValue(const std::string &key,
+ const std::string &value,
+ std::string *newKey) {
+ // if key exists, add suffix to avoid overwriting exisiting values, newKey
+ // saves newly assigned key, if newKey is nullptr, original key is used
+ std::string tmpKey = key;
+ bool dup = false;
+ if (newKey != nullptr) {
+ uint64_t counter = 0;
+ while (true) {
+ *newKey = key + std::to_string(counter);
+ if (ref->commonvalue().find(*newKey) == ref->commonvalue().end()) {
+ tmpKey = *newKey;
+ break; // found new key
+ } else if (ref->commonvalue().at(*newKey) == value) {
+ tmpKey = *newKey;
+ dup = true;
+ break; // found duplicate value, no need to allocate new key
+ }
+ counter++;
+ }
+ }
+ if (!dup) {
+ (*ref->mutable_commonvalue())[tmpKey] = value;
+ LOG_DEBUG("set key %s into common values of plan size %lu", tmpKey.c_str(),
+ value.size());
+ } else {
+ LOG_DEBUG("found duplicate key %s", tmpKey.c_str());
+ }
+}
+
+void UnivPlanBuilderPlan::setDoInstrument(bool doInstrument) {
+ ref->set_doinstrument(doInstrument);
+}
+
+void UnivPlanBuilderPlan::setNCrossLevelParams(int32_t nCrossLevelParams) {
+ ref->set_ncrosslevelparams(nCrossLevelParams);
+}
+
+void UnivPlanBuilderPlan::setCmdType(UNIVPLANCMDTYPE cmdType) {
+ ref->set_cmdtype(cmdType);
+}
+
+// xxx only called from stagize, need sync with univplanplan's fields
+void UnivPlanBuilderPlan::from(const UnivPlanPlan &from) {
+ // plan not set
+ ref->set_stageno(from.stageno());
+ if (from.snapshot().empty() == false) ref->set_snapshot(from.snapshot());
+ ref->set_doinstrument(from.doinstrument());
+ ref->set_ncrosslevelparams(from.ncrosslevelparams());
+ ref->set_cmdtype(from.cmdtype());
+ for (int i = 0; i < from.rangetables_size(); i++)
+ ref->add_rangetables()->CopyFrom(from.rangetables(i));
+ for (int i = 0; i < from.tokenmap_size(); i++)
+ ref->add_tokenmap()->CopyFrom(from.tokenmap(i));
+ for (int i = 0; i < from.receivers_size(); i++)
+ ref->add_receivers()->CopyFrom(from.receivers(i));
+ for (int i = 0; i < from.paraminfos_size(); ++i)
+ ref->add_paraminfos()->CopyFrom(from.paraminfos(i));
+ for (auto ent : from.guc()) (*ref->mutable_guc())[ent.first] = ent.second;
+ for (auto ent : from.commonvalue())
+ (*ref->mutable_commonvalue())[ent.first] = ent.second;
+
+ // childStage not set
+}
+
+UnivPlanBuilderRangeTblEntry::uptr
+UnivPlanBuilderPlan::addRangeTblEntryAndGetBuilder() {
+ UnivPlanRangeTblEntry *entry = ref->add_rangetables();
+ UnivPlanBuilderRangeTblEntry::uptr bld(
+ new UnivPlanBuilderRangeTblEntry(entry));
+ return std::move(bld);
+}
+
+UnivPlanBuilderReceiver::uptr UnivPlanBuilderPlan::addReceiverAndGetBuilder() {
+ UnivPlanReceiver *receiver = ref->add_receivers();
+ UnivPlanBuilderReceiver::uptr bld(new UnivPlanBuilderReceiver(receiver));
+ return std::move(bld);
+}
+
+UnivPlanBuilderParamInfo::uptr
+UnivPlanBuilderPlan::addParamInfoAndGetBuilder() {
+ UnivPlanParamInfo *paramInfo = ref->add_paraminfos();
+ UnivPlanBuilderParamInfo::uptr bld(new UnivPlanBuilderParamInfo(paramInfo));
+ return std::move(bld);
+}
+
+UnivPlanBuilderPlan::uptr UnivPlanBuilderPlan::addChildStageAndGetBuilder() {
+ UnivPlanPlan *child = ref->add_childstages();
+ UnivPlanBuilderPlan::uptr bld(new UnivPlanBuilderPlan(child));
+ return std::move(bld);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan.h
new file mode 100644
index 0000000..a572f08
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-plan.h
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PLAN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PLAN_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+#include "univplan/univplanbuilder/univplanbuilder-paraminfo.h"
+#include "univplan/univplanbuilder/univplanbuilder-range-tbl-entry.h"
+#include "univplan/univplanbuilder/univplanbuilder-receiver.h"
+
+namespace univplan {
+
+class UnivPlanBuilderPlan {
+ public:
+ UnivPlanBuilderPlan() {
+ plan.reset(new UnivPlanPlan());
+ ref = plan.get();
+ }
+
+ explicit UnivPlanBuilderPlan(UnivPlanPlan *plan) : ref(plan) {}
+
+ virtual ~UnivPlanBuilderPlan() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderPlan> uptr;
+
+ UnivPlanPlan *getPlan() { return ref; }
+ UnivPlanPlan *ownPlan() { return plan.release(); }
+
+ // set root node of the plan
+ void setPlanNode(UnivPlanBuilderPlanNodePoly::uptr pn);
+ void setSubplanNode(UnivPlanBuilderPlanNodePoly::uptr pn);
+ bool isSettingSubplan() { return ref->has_plan(); }
+
+ void setStageNo(int32_t stageNo);
+ void setDoInstrument(bool doInstrument);
+ void setNCrossLevelParams(int32_t nCrossLevelParams);
+ void setCmdType(UNIVPLANCMDTYPE cmdType);
+
+ void from(const UnivPlanPlan &from);
+ void setTokenEntry(std::string protocol, std::string host, int port,
+ std::string token);
+ void setSnapshot(const std::string &snapshot);
+
+ void addGuc(const std::string &name, const std::string &value);
+
+ void addCommonValue(const std::string &key, const std::string &value,
+ std::string *newKey);
+
+ UnivPlanBuilderRangeTblEntry::uptr addRangeTblEntryAndGetBuilder();
+
+ UnivPlanBuilderReceiver::uptr addReceiverAndGetBuilder();
+
+ UnivPlanBuilderParamInfo::uptr addParamInfoAndGetBuilder();
+
+ UnivPlanBuilderPlan::uptr addChildStageAndGetBuilder();
+
+ private:
+ UnivPlanPlan *ref;
+ std::unique_ptr<UnivPlanPlan> plan;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_PLAN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-range-tbl-entry.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-range-tbl-entry.h
new file mode 100644
index 0000000..6d432ba
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-range-tbl-entry.h
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RANGE_TBL_ENTRY_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RANGE_TBL_ENTRY_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+class UnivPlanBuilderRangeTblEntry {
+ public:
+ UnivPlanBuilderRangeTblEntry() {
+ node.reset(new UnivPlanRangeTblEntry());
+ ref = node.get();
+ }
+
+ explicit UnivPlanBuilderRangeTblEntry(UnivPlanRangeTblEntry *rangeTblEntry)
+ : ref(rangeTblEntry) {}
+
+ virtual ~UnivPlanBuilderRangeTblEntry() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderRangeTblEntry> uptr;
+
+ void setTable(std::unique_ptr<UnivPlanTable> table) {
+ ref->set_allocated_table(table.release());
+ }
+
+ private:
+ UnivPlanRangeTblEntry *ref;
+ std::unique_ptr<UnivPlanRangeTblEntry> node;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RANGE_TBL_ENTRY_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-receiver.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-receiver.h
new file mode 100644
index 0000000..ebf26ef
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-receiver.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RECEIVER_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RECEIVER_H_
+
+#include <string>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-listener.h"
+
+namespace univplan {
+
+class UnivPlanBuilderReceiver {
+ public:
+ explicit UnivPlanBuilderReceiver(UnivPlanReceiver *receiver)
+ : ref(receiver) {}
+
+ virtual ~UnivPlanBuilderReceiver() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderReceiver> uptr;
+
+ UnivPlanBuilderListener::uptr addPlanListenerAndGetBuilder() {
+ UnivPlanListener *listener = ref->add_listener();
+ UnivPlanBuilderListener::uptr bld(new UnivPlanBuilderListener(listener));
+ return std::move(bld);
+ }
+
+ private:
+ UnivPlanReceiver *ref;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RECEIVER_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-result.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-result.h
new file mode 100644
index 0000000..adb05e6
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-result.h
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RESULT_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RESULT_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderResult : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderResult() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanResult());
+ ref = planNode.get();
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderResult() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderResult> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_RESULT, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_result(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_RESULT);
+ ref->CopyFrom(node.result());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ void addResConstantQual(UnivPlanBuilderExprTree::uptr exprTree) {
+ assert(ref != nullptr);
+ ref->mutable_resconstantqual()->AddAllocated(
+ exprTree->ownExprPoly().release());
+ }
+
+ private:
+ UnivPlanResult *ref;
+ std::unique_ptr<UnivPlanResult> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_RESULT_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-seq.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-seq.cc
new file mode 100644
index 0000000..4bb93c3
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-seq.cc
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-scan-seq.h"
+
+namespace univplan {
+
+UnivPlanBuilderScanSeq::UnivPlanBuilderScanSeq() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanScanSeq);
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderScanSeq::~UnivPlanBuilderScanSeq() {}
+
+std::unique_ptr<UnivPlanBuilderPlanNodePoly>
+UnivPlanBuilderScanSeq::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_SCAN_SEQ, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_scanseq(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderScanSeq::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_SCAN_SEQ);
+ ref->CopyFrom(node.scanseq());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderScanSeq::setScanRelId(uint32_t id) { ref->set_relid(id); }
+
+void UnivPlanBuilderScanSeq::setColumnsToRead(
+ const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_columnstoread(nArray[i]);
+ }
+}
+
+void UnivPlanBuilderScanSeq::setReadStatsOnly(bool readStatsOnly) {
+ ref->set_readstatsonly(readStatsOnly);
+}
+
+UnivPlanBuilderScanTask::uptr
+UnivPlanBuilderScanSeq::addScanTaskAndGetBuilder() {
+ UnivPlanScanTask *task = ref->add_tasks();
+ std::unique_ptr<UnivPlanBuilderScanTask> res(
+ new UnivPlanBuilderScanTask(task));
+ return std::move(res);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-seq.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-seq.h
new file mode 100644
index 0000000..eee1cb7
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-seq.h
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SCAN_SEQ_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SCAN_SEQ_H_
+
+#include <string>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+#include "univplan/univplanbuilder/univplanbuilder-scan-task.h"
+
+namespace univplan {
+
+class UnivPlanBuilderScanSeq : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderScanSeq();
+ virtual ~UnivPlanBuilderScanSeq();
+
+ typedef std::unique_ptr<UnivPlanBuilderScanSeq> uptr;
+
+ std::unique_ptr<UnivPlanBuilderPlanNodePoly> ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setScanRelId(uint32_t id);
+ void setColumnsToRead(const std::vector<int32_t> &nArray);
+ void setReadStatsOnly(bool readStatsOnly);
+
+ UnivPlanBuilderScanTask::uptr addScanTaskAndGetBuilder();
+
+ private:
+ UnivPlanScanSeq *ref;
+ std::unique_ptr<UnivPlanScanSeq> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SCAN_SEQ_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-task.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-task.h
new file mode 100644
index 0000000..c4e4dab
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-scan-task.h
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SCAN_TASK_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SCAN_TASK_H_
+
+#include <string>
+
+#include "dbcommon/common/tuple-batch.h"
+
+#include "univplan/proto/universal-plan.pb.h"
+
+namespace univplan {
+
+#define TBSPLITS_COL_INDEX_FILENAME 0
+#define TBSPLITS_COL_INDEX_START 1
+#define TBSPLITS_COL_INDEX_LEN 2
+#define TBSPLITS_COL_INDEX_RANGEID 3
+#define TBSPLITS_COL_INDEX_RGID 4
+
+class UnivPlanBuilderScanTask {
+ public:
+ UnivPlanBuilderScanTask() { prepare(); }
+ explicit UnivPlanBuilderScanTask(UnivPlanScanTask *task) {
+ ref = task;
+ prepare();
+ }
+ virtual ~UnivPlanBuilderScanTask() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderScanTask> uptr;
+
+ void prepare(void) {
+ if (tbSplitsDesc_.getNumOfColumns() == 0) {
+ // initialize tuple desc only once, col names are not meaningful
+ tbSplitsDesc_.add("f", dbcommon::TypeKind::STRINGID);
+ tbSplitsDesc_.add("s", dbcommon::TypeKind::BIGINTID);
+ tbSplitsDesc_.add("l", dbcommon::TypeKind::BIGINTID);
+ tbSplitsDesc_.add("rid", dbcommon::TypeKind::BIGINTID);
+ tbSplitsDesc_.add("rgid", dbcommon::TypeKind::INTID);
+ }
+ tbSplits_.reset(new dbcommon::TupleBatch(tbSplitsDesc_, true));
+ }
+
+ void addScanFileSplit(const char *filename, int64_t start, int64_t len,
+ int64_t rangeid, int32_t rgid) {
+ dbcommon::TupleBatchWriter &writers = tbSplits_->getTupleBatchWriter();
+ writers[TBSPLITS_COL_INDEX_FILENAME]->append(filename, strlen(filename),
+ false);
+ writers[TBSPLITS_COL_INDEX_START]->append(reinterpret_cast<char *>(&start),
+ sizeof(int64_t), false);
+ writers[TBSPLITS_COL_INDEX_LEN]->append(reinterpret_cast<char *>(&len),
+ sizeof(int64_t), false);
+ writers[TBSPLITS_COL_INDEX_RANGEID]->append(
+ reinterpret_cast<char *>(&rangeid), sizeof(int64_t), false);
+ writers[TBSPLITS_COL_INDEX_RGID]->append(reinterpret_cast<char *>(&rgid),
+ sizeof(int32_t), false);
+ tbSplits_->incNumOfRows(1);
+ }
+
+ void generate(void) {
+ std::unique_ptr<std::string> serialized(new std::string());
+ if (tbSplits_->getNumOfRows() > 0) {
+ tbSplits_->serialize(serialized.get(), 0);
+ ref->set_allocated_serializedsplits(serialized.release());
+ }
+ }
+
+ dbcommon::TupleBatch::uptr releaseSplitsTb() { return std::move(tbSplits_); }
+
+ private:
+ UnivPlanScanTask *ref = nullptr;
+ dbcommon::TupleDesc tbSplitsDesc_;
+ dbcommon::TupleBatch::uptr tbSplits_;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SCAN_TASK_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-shareinput-scan.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-shareinput-scan.h
new file mode 100644
index 0000000..4c521ad
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-shareinput-scan.h
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SHAREINPUT_SCAN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SHAREINPUT_SCAN_H_
+
+#include <memory>
+#include <utility>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderShareInputScan : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderShareInputScan() : UnivPlanBuilderNode() {
+ planNode_.reset(new UnivPlanShareInputScan());
+ ref_ = planNode_.get();
+ ref_->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderShareInputScan() {}
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(new UnivPlanBuilderPlanNodePoly(
+ UNIVPLAN_SHAREINPUTSCAN, planNode_->super()));
+ pn->getPlanNodePoly()->set_allocated_shareinputscan(planNode_.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_SHAREINPUTSCAN);
+ ref_->CopyFrom(node.shareinputscan());
+ baseRef = ref_->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ void setShareType(UNIVPLANSHARETYPE type) { ref_->set_sharetype(type); }
+
+ void setShareId(int32_t shareId) { ref_->set_sharedid(shareId); }
+
+ void setDriverSlice(int32_t driverSlice) {
+ ref_->set_driverslice(driverSlice);
+ }
+
+ private:
+ UnivPlanShareInputScan *ref_;
+ std::unique_ptr<UnivPlanShareInputScan> planNode_;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SHAREINPUT_SCAN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sink.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sink.h
new file mode 100644
index 0000000..6787621
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sink.h
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SINK_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SINK_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+// this class is only used in stagize
+class UnivPlanBuilderSinkInput : public UnivPlanBuilderNode {
+ public:
+ typedef std::unique_ptr<UnivPlanBuilderSinkInput> uptr;
+ UnivPlanBuilderSinkInput() : UnivPlanBuilderNode() {}
+ virtual ~UnivPlanBuilderSinkInput() {}
+ virtual void setTargetStageNo(int32_t targetStageNo) = 0;
+ virtual int32_t getTargetStageNo() = 0;
+ virtual void setCurrentStageNo(int32_t targetStageNo) = 0;
+ virtual int32_t getCurrentStageNo() = 0;
+ virtual void from(const UnivPlanConnector &from) {
+ baseRef->CopyFrom(from.super());
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+ // virtual UNIVPLANNODETYPE getType() = 0;
+};
+
+class UnivPlanBuilderSink : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderSink() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanSink());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderSink() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderSink> uptr;
+
+ // only used in stagize
+ void from(const UnivPlanConnector &from) {
+ baseRef->CopyFrom(from.super());
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ ref->set_connectortype(from.type());
+ for (int i = 0; i < from.colidx_size(); ++i)
+ ref->add_colidx(from.colidx(i));
+ for (int i = 0; i < from.sortfuncid_size(); ++i)
+ ref->add_sortfuncid(from.sortfuncid(i));
+ }
+
+ void setSourceStageNo(int32_t sourceStageNo) {
+ ref->set_sourcestageno(sourceStageNo);
+ }
+
+ void setCurrentStageNo(int32_t currentStageNo) {
+ ref->set_currentstageno(currentStageNo);
+ }
+
+ void setConnectorType(UNIVPLANCONNECTORTYPE connectorType) {
+ ref->set_connectortype(connectorType);
+ }
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_SINK, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_sink(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_SINK);
+ ref->CopyFrom(node.sink());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ private:
+ UnivPlanSink *ref;
+ std::unique_ptr<UnivPlanSink> planNode;
+};
+
+class UnivPlanBuilderConverge : public UnivPlanBuilderSinkInput {
+ public:
+ UnivPlanBuilderConverge() : UnivPlanBuilderSinkInput() {
+ planNode.reset(new UnivPlanConverge());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderConverge() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderConverge> uptr;
+
+ void from(const UnivPlanConnector &from) override {
+ UnivPlanBuilderSinkInput::from(from);
+ }
+
+ void setTargetStageNo(int32_t targetStageNo) override {
+ ref->set_targetstageno(targetStageNo);
+ }
+
+ int32_t getTargetStageNo() override { return ref->targetstageno(); }
+
+ void setCurrentStageNo(int32_t currentStageNo) override {
+ ref->set_currentstageno(currentStageNo);
+ }
+
+ int32_t getCurrentStageNo() override { return ref->currentstageno(); }
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_CONVERGE, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_converge(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_CONVERGE);
+ ref->CopyFrom(node.converge());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ private:
+ UnivPlanConverge *ref;
+ std::unique_ptr<UnivPlanConverge> planNode;
+};
+
+class UnivPlanBuilderShuffle : public UnivPlanBuilderSinkInput {
+ public:
+ UnivPlanBuilderShuffle() : UnivPlanBuilderSinkInput() {
+ planNode.reset(new UnivPlanShuffle());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderShuffle() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderShuffle> uptr;
+
+ void from(const UnivPlanConnector &from) override {
+ UnivPlanBuilderSinkInput::from(from);
+ ref->set_magmatable(from.magmatable());
+ ref->mutable_hashexpr()->CopyFrom(from.hashexpr());
+ ref->mutable_magmamap()->CopyFrom(from.magmamap());
+ ref->set_rangenum(from.rangenum());
+ }
+
+ void setTargetStageNo(int32_t targetStageNo) override {
+ ref->set_targetstageno(targetStageNo);
+ }
+
+ int32_t getTargetStageNo() override { return ref->targetstageno(); }
+
+ void setCurrentStageNo(int32_t currentStageNo) override {
+ ref->set_currentstageno(currentStageNo);
+ }
+
+ int32_t getCurrentStageNo() override { return ref->currentstageno(); }
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_SHUFFLE, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_shuffle(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_SHUFFLE);
+ ref->CopyFrom(node.shuffle());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ private:
+ UnivPlanShuffle *ref;
+ std::unique_ptr<UnivPlanShuffle> planNode;
+};
+
+class UnivPlanBuilderBroadcast : public UnivPlanBuilderSinkInput {
+ public:
+ UnivPlanBuilderBroadcast() : UnivPlanBuilderSinkInput() {
+ planNode.reset(new UnivPlanBroadcast());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderBroadcast() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderBroadcast> uptr;
+
+ void from(const UnivPlanConnector &from) override {
+ UnivPlanBuilderSinkInput::from(from);
+ }
+
+ void setTargetStageNo(int32_t targetStageNo) override {
+ ref->set_targetstageno(targetStageNo);
+ }
+
+ int32_t getTargetStageNo() override { return ref->targetstageno(); }
+
+ void setCurrentStageNo(int32_t currentStageNo) override {
+ ref->set_currentstageno(currentStageNo);
+ }
+
+ int32_t getCurrentStageNo() override { return ref->currentstageno(); }
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_BROADCAST, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_broadcast(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_BROADCAST);
+ ref->CopyFrom(node.broadcast());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ }
+
+ private:
+ UnivPlanBroadcast *ref;
+ std::unique_ptr<UnivPlanBroadcast> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SINK_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sort.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sort.cc
new file mode 100644
index 0000000..be1d9eb
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sort.cc
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-sort.h"
+
+namespace univplan {
+
+UnivPlanBuilderSort::UnivPlanBuilderSort() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanSort());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderPlanNodePoly::uptr UnivPlanBuilderSort::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_SORT, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_sort(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderSort::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_SORT);
+ ref->CopyFrom(node.sort());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderSort::setColIdx(const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_colidx(nArray[i]);
+ }
+}
+void UnivPlanBuilderSort::setSortFuncId(const std::vector<int32_t> &nArray) {
+ for (int i = 0; i < nArray.size(); ++i) {
+ ref->add_sortfuncid(nArray[i]);
+ }
+}
+
+void UnivPlanBuilderSort::setLimitOffset(UnivPlanBuilderExprTree::uptr offset) {
+ ref->set_allocated_limitoffset(offset->ownExprPoly().release());
+}
+
+void UnivPlanBuilderSort::setLimitCount(UnivPlanBuilderExprTree::uptr count) {
+ ref->set_allocated_limitcount(count->ownExprPoly().release());
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sort.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sort.h
new file mode 100644
index 0000000..7c3ee35
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-sort.h
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SORT_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SORT_H_
+
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderSort : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderSort();
+ virtual ~UnivPlanBuilderSort() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderSort> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setColIdx(const std::vector<int32_t> &nArray);
+ void setSortFuncId(const std::vector<int32_t> &nArray);
+
+ void setLimitOffset(UnivPlanBuilderExprTree::uptr limitOffset);
+ void setLimitCount(UnivPlanBuilderExprTree::uptr limitCount);
+
+ private:
+ UnivPlanSort *ref;
+ std::unique_ptr<UnivPlanSort> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SORT_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-subquery-scan.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-subquery-scan.h
new file mode 100644
index 0000000..ddb4767
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-subquery-scan.h
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SUBQUERY_SCAN_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SUBQUERY_SCAN_H_
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderSubqueryScan : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderSubqueryScan() {
+ planNode.reset(new UnivPlanSubqueryScan());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+ }
+ virtual ~UnivPlanBuilderSubqueryScan() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderSubqueryScan> uptr;
+
+ std::unique_ptr<UnivPlanBuilderPlanNodePoly> ownPlanNode() override {
+ UnivPlanBuilderPlanNodePoly::uptr pn(new UnivPlanBuilderPlanNodePoly(
+ UNIVPLAN_SUBQUERYSCAN, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_subqueryscan(planNode.release());
+ return std::move(pn);
+ }
+
+ void from(const UnivPlanPlanNodePoly &node) override {
+ assert(node.type() == UNIVPLAN_SUBQUERYSCAN);
+ ref->CopyFrom(node.subqueryscan());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+ ref->clear_subplan();
+ }
+
+ void setSubPlan(const UnivPlanPlanNodePoly &node) {
+ ref->mutable_subplan()->CopyFrom(node);
+ }
+
+ private:
+ UnivPlanSubqueryScan *ref;
+ std::unique_ptr<UnivPlanSubqueryScan> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_SUBQUERY_SCAN_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-table.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-table.h
new file mode 100644
index 0000000..e5e0b6b
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-table.h
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_TABLE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_TABLE_H_
+
+#include <string>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-column.h"
+
+namespace univplan {
+
+class UnivPlanBuilderTable {
+ public:
+ UnivPlanBuilderTable() {
+ node.reset(new UnivPlanTable());
+ ref = node.get();
+ }
+ virtual ~UnivPlanBuilderTable() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderTable> uptr;
+
+ std::unique_ptr<UnivPlanTable> ownTable() { return std::move(node); }
+
+ void setTableId(int64_t id) { ref->set_tableid(id); }
+
+ void setTableFormat(UNIVPLANFORMATTYPE type) { ref->set_format(type); }
+
+ void setTableLocation(const std::string &location) {
+ ref->set_location(location);
+ }
+
+ void setTableOptionsInJson(const std::string &optStr) {
+ ref->set_tableoptionsinjson(optStr);
+ }
+
+ UnivPlanBuilderColumn::uptr addPlanColumnAndGetBuilder() {
+ UnivPlanColumn *column = ref->add_columns();
+ UnivPlanBuilderColumn::uptr bld(new UnivPlanBuilderColumn(column));
+ return std::move(bld);
+ }
+
+ private:
+ UnivPlanTable *ref;
+ std::unique_ptr<UnivPlanTable> node;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_TABLE_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-target-entry.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-target-entry.h
new file mode 100644
index 0000000..c3fbdeb
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-target-entry.h
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_TARGET_ENTRY_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_TARGET_ENTRY_H_
+
+#include "univplan/univplanbuilder/univplanbuilder-expr-node.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-tree.h"
+
+namespace univplan {
+
+class UnivPlanBuilderTargetEntry : public UnivPlanBuilderExprNode {
+ public:
+ UnivPlanBuilderTargetEntry() {
+ node.reset(new UnivPlanTargetEntry());
+ ref = node.get();
+ }
+
+ explicit UnivPlanBuilderTargetEntry(UnivPlanTargetEntry *targetEntry)
+ : ref(targetEntry) {}
+
+ virtual ~UnivPlanBuilderTargetEntry() {}
+
+ typedef std::unique_ptr<UnivPlanBuilderTargetEntry> uptr;
+
+ UnivPlanBuilderExprPoly::uptr getExprPolyBuilder() {
+ assert(node != nullptr);
+ UnivPlanBuilderExprPoly::uptr exprPoly(
+ new UnivPlanBuilderExprPoly(UNIVPLAN_EXPR_TARGETENTRY));
+ exprPoly->getExprPoly()->set_allocated_targetentry(node.release());
+ return std::move(exprPoly);
+ }
+
+ void setResJunk(bool resJunk) { ref->set_resjunk(resJunk); }
+
+ void setExpr(UnivPlanBuilderExprPoly::uptr exprPoly) {
+ ref->set_allocated_expression(exprPoly->ownExprPoly().release());
+ }
+
+ void setExpr(UnivPlanBuilderExprTree::uptr expr) {
+ ref->set_allocated_expression(expr->ownExprPoly().release());
+ }
+
+ private:
+ UnivPlanTargetEntry *ref = nullptr;
+ std::unique_ptr<UnivPlanTargetEntry> node;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_TARGET_ENTRY_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-unique.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-unique.cc
new file mode 100644
index 0000000..fd03ca5
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-unique.cc
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder-unique.h"
+
+#include <utility>
+
+namespace univplan {
+
+UnivPlanBuilderUnique::UnivPlanBuilderUnique() : UnivPlanBuilderNode() {
+ planNode.reset(new UnivPlanUnique());
+ ref = planNode.get();
+
+ ref->set_allocated_super(UnivPlanBuilderNode::basePlanNode.release());
+}
+
+UnivPlanBuilderUnique::~UnivPlanBuilderUnique() {}
+
+UnivPlanBuilderPlanNodePoly::uptr UnivPlanBuilderUnique::ownPlanNode() {
+ UnivPlanBuilderPlanNodePoly::uptr pn(
+ new UnivPlanBuilderPlanNodePoly(UNIVPLAN_UNIQUE, planNode->super()));
+ pn->getPlanNodePoly()->set_allocated_unique(planNode.release());
+ return std::move(pn);
+}
+
+void UnivPlanBuilderUnique::from(const UnivPlanPlanNodePoly &node) {
+ assert(node.type() == UNIVPLAN_UNIQUE);
+ ref->CopyFrom(node.unique());
+ baseRef = ref->mutable_super();
+ baseRef->clear_leftplan();
+ baseRef->clear_rightplan();
+}
+
+void UnivPlanBuilderUnique::setUniqColIdxs(size_t numCols,
+ const int32_t *uniqColIdxs) {
+ for (int i = 0; i < numCols; ++i) {
+ ref->add_uniqcolidxs(uniqColIdxs[i]);
+ }
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-unique.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-unique.h
new file mode 100644
index 0000000..e89747e
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder-unique.h
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_UNIQUE_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_UNIQUE_H_
+
+#include <memory>
+#include <vector>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+
+namespace univplan {
+
+class UnivPlanBuilderUnique : public UnivPlanBuilderNode {
+ public:
+ UnivPlanBuilderUnique();
+ virtual ~UnivPlanBuilderUnique();
+
+ typedef std::unique_ptr<UnivPlanBuilderUnique> uptr;
+
+ UnivPlanBuilderPlanNodePoly::uptr ownPlanNode() override;
+
+ void from(const UnivPlanPlanNodePoly &node) override;
+
+ void setUniqColIdxs(size_t numCols, const int32_t *uniqColIdxs);
+
+ private:
+ UnivPlanUnique *ref;
+ std::unique_ptr<UnivPlanUnique> planNode;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_UNIQUE_H_
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder.cc b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder.cc
new file mode 100644
index 0000000..44032c4
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder.cc
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "univplan/univplanbuilder/univplanbuilder.h"
+
+#include <utility>
+
+#include "dbcommon/log/logger.h"
+#include "dbcommon/type/type-kind.h"
+
+namespace univplan {
+
+typedef dbcommon::TypeKind TypeKind;
+
+UnivPlanBuilderPlan::uptr UnivPlanBuilder::swapBuilder(
+ UnivPlanBuilderPlan::uptr newBuilder) {
+ UnivPlanBuilderPlan::uptr ret = std::move(builder);
+ builder = std::move(newBuilder);
+ return std::move(ret);
+}
+
+void UnivPlanBuilder::addPlanNode(bool isleft, UnivPlanBuilderNode::uptr bld) {
+ UnivPlanBuilderPlanNodePoly::uptr pn = bld->ownPlanNode();
+ int32_t uid = bld->uid; // required field
+ int32_t pid = bld->pid; // required field
+
+ // Check if this node has node id set already
+ if (uid < 0)
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "UnivPlanBuilder::addPlanNode uid is negative");
+
+ // Check if the id is unique
+ if (idToPlanNodes.find(uid) != idToPlanNodes.end())
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "UnivPlanBuilder::addPlanNode uid is duplicate");
+
+ // Use hash table to track this node quickly
+ idToPlanNodes[uid] = std::move(bld);
+
+ UnivPlanPlan *plan = builder->getPlan();
+
+ if (pid < 0) {
+ // If a node has no parent id, it is a root node of the plan or subplan.
+ if (builder->isSettingSubplan())
+ builder->setSubplanNode(std::move(pn));
+ else
+ builder->setPlanNode(std::move(pn));
+
+ } else {
+ // If this node has a parent id, that means this node should be connected
+ // to its expected parent node.
+
+ // Find its parent node if its parent id is specified
+ if (idToPlanNodes.find(pid) == idToPlanNodes.end())
+ LOG_ERROR(ERRCODE_INTERNAL_ERROR,
+ "UnivPlanBuilder::addPlanNode unexpected parent id %d found",
+ pid);
+
+ // add to parent node
+ if (isleft) {
+ idToPlanNodes[pid]->setNodeLeftPlan(std::move(pn));
+ } else {
+ idToPlanNodes[pid]->setNodeRightPlan(std::move(pn));
+ }
+ }
+}
+
+std::string UnivPlanBuilder::getJsonFormatedPlan() {
+ return builder->getPlan()->DebugString();
+}
+
+std::string UnivPlanBuilder::serialize() {
+ return builder->getPlan()->SerializeAsString();
+}
+
+} // namespace univplan
diff --git a/depends/univplan/src/univplan/univplanbuilder/univplanbuilder.h b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder.h
new file mode 100644
index 0000000..f8e2f0b
--- /dev/null
+++ b/depends/univplan/src/univplan/univplanbuilder/univplanbuilder.h
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_H_
+#define UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_H_
+
+#include <map>
+#include <string>
+
+#include "univplan/proto/universal-plan.pb.h"
+#include "univplan/univplanbuilder/univplanbuilder-node.h"
+#include "univplan/univplanbuilder/univplanbuilder-plan.h"
+
+namespace univplan {
+
+class UnivPlanBuilder {
+ public:
+ UnivPlanBuilder() {
+ builder.reset(new UnivPlanBuilderPlan());
+ idToPlanNodes.clear();
+ }
+ virtual ~UnivPlanBuilder() {}
+
+ typedef std::unique_ptr<UnivPlanBuilder> uptr;
+
+ int32_t getUid() { return nodeCounter++; }
+ UnivPlanBuilderPlan *getPlanBuilderPlan() { return builder.get(); }
+ UnivPlanBuilderPlan::uptr swapBuilder(UnivPlanBuilderPlan::uptr newBuilder);
+
+ //----------------------------
+ // Add plan node to this plan
+ //----------------------------
+ void addPlanNode(bool isleft, // as its parent's left child
+ UnivPlanBuilderNode::uptr bld);
+
+ //-----------------------------
+ // Utility
+ //-----------------------------
+ std::string getJsonFormatedPlan();
+
+ std::string serialize();
+
+ private:
+ UnivPlanBuilderPlan::uptr builder;
+
+ int32_t nodeCounter = 0;
+ std::map<int32_t, UnivPlanBuilderNode::uptr> idToPlanNodes;
+};
+
+} // namespace univplan
+
+#endif // UNIVPLAN_SRC_UNIVPLAN_UNIVPLANBUILDER_UNIVPLANBUILDER_H_
diff --git a/depends/univplan/test/CMakeLists.txt b/depends/univplan/test/CMakeLists.txt
new file mode 100644
index 0000000..088ab7f
--- /dev/null
+++ b/depends/univplan/test/CMakeLists.txt
@@ -0,0 +1,33 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+SET(CMAKE_BUILD_TYPE "Debug")
+SET(TEST_WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data/)
+ADD_DEFINITIONS(-DDATA_DIR="${TEST_WORKING_DIR}/")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
+
+INCLUDE_DIRECTORIES(${univplan_ROOT_DIR})
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/src)
+INCLUDE_DIRECTORIES(${DEPENDENCY_INSTALL_PREFIX}/package/include)
+
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/src)
+LINK_DIRECTORIES(${DEPENDENCY_INSTALL_PREFIX}/package/lib)
+
+ADD_SUBDIRECTORY(unit)
+
+IF(TEST_RUNNER)
+ SEPARATE_ARGUMENTS(TEST_RUNNER_LIST UNIX_COMMAND ${TEST_RUNNER})
+ENDIF(TEST_RUNNER)
+
+ADD_CUSTOM_TARGET(unittest
+ COMMAND ${TEST_RUNNER_LIST} ${CMAKE_CURRENT_BINARY_DIR}/unit/unit
+ DEPENDS unit
+ WORKING_DIRECTORY ${TEST_WORKING_DIR}
+ COMMENT "Run Unit Test..."
+)
+
+ADD_CUSTOM_TARGET(punittest
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/parallel/parallel-launcher.py ${TEST_RUNNER_LIST} ${CMAKE_CURRENT_BINARY_DIR}/unit/unit
+ DEPENDS unit
+ WORKING_DIRECTORY ${TEST_WORKING_DIR}
+ COMMENT "Run Unit Test in parallel..."
+)
diff --git a/depends/univplan/test/data/TestAgg b/depends/univplan/test/data/TestAgg
new file mode 100644
index 0000000..c20fd96
--- /dev/null
+++ b/depends/univplan/test/data/TestAgg
@@ -0,0 +1,260 @@
+plan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_AGG
+ agg {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_AGGREF
+ aggref {
+ transFuncId: 494
+ retType: 103
+ transInitVal: true
+ finalFuncId: 38324
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 65001
+ varAttNo: 1
+ typeId: 103
+ typeMod: -1
+ }
+ }
+ funcId: 492
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_AGG
+ agg {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_AGGREF
+ aggref {
+ transFuncId: 493
+ retType: 103
+ transInitVal: true
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 65001
+ varAttNo: 1
+ typeId: 103
+ typeMod: -1
+ }
+ }
+ funcId: 492
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ numGroups: 1000
+ groupColIndexes: 1
+ groupColIndexes: 3
+ }
+ }
+ }
+ type: CONNECTORTYPE_SHUFFLE
+ hashExpr {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 0
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ numGroups: 1000
+ groupColIndexes: 1
+ groupColIndexes: 3
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+}
diff --git a/depends/univplan/test/data/TestCompletedPlanAfter b/depends/univplan/test/data/TestCompletedPlanAfter
new file mode 100644
index 0000000..c40ea64
--- /dev/null
+++ b/depends/univplan/test/data/TestCompletedPlanAfter
@@ -0,0 +1,849 @@
+plan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SINK
+ sink {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ connectorType: CONNECTORTYPE_CONVERGE
+ sourceStageNo: 2
+ currentStageNo: 0
+ }
+ }
+ planRows: 110
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+}
+childStages {
+ plan {
+ type: UNIVPLAN_CONVERGE
+ converge {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_AGG
+ agg {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_AGGREF
+ aggref {
+ transFuncId: 494
+ retType: 103
+ transInitVal: true
+ finalFuncId: 38324
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 65001
+ varAttNo: 1
+ typeId: 103
+ typeMod: -1
+ }
+ }
+ funcId: 492
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SINK
+ sink {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ connectorType: CONNECTORTYPE_SHUFFLE
+ sourceStageNo: 1
+ currentStageNo: 2
+ }
+ }
+ }
+ numGroups: 1000
+ groupColIndexes: 1
+ groupColIndexes: 3
+ }
+ }
+ planRows: 110
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "0"
+ typeMod: -1
+ }
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 339
+ retType: 103
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ targetStageNo: 0
+ currentStageNo: 2
+ }
+ }
+ childStages {
+ plan {
+ type: UNIVPLAN_SHUFFLE
+ shuffle {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_AGG
+ agg {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_AGGREF
+ aggref {
+ transFuncId: 493
+ retType: 103
+ transInitVal: true
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 65001
+ varAttNo: 1
+ typeId: 103
+ typeMod: -1
+ }
+ }
+ funcId: 492
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 158
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 92
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 35
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_FUNCEXPR
+ funcexpr {
+ funcId: 0
+ retType: 300
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_BOOLEXPR
+ boolexpr {
+ args {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 164
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 14
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ type: BOOLEXPRTYPE_OR_EXPR
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ numGroups: 1000
+ groupColIndexes: 1
+ groupColIndexes: 3
+ }
+ }
+ }
+ targetStageNo: 2
+ currentStageNo: 1
+ hashExpr {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 0
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ magmaTable: false
+ rangeNum: 0
+ }
+ }
+ rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+ }
+ rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ }
+ receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+ }
+ receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+ }
+ stageNo: 1
+ doInstrument: true
+ nCrossLevelParams: 0
+ commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+ }
+ cmdType: CMD_SELECT
+ }
+ rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+ }
+ rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ }
+ receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+ }
+ receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+ }
+ stageNo: 2
+ doInstrument: true
+ nCrossLevelParams: 0
+ commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+ }
+ cmdType: CMD_SELECT
+}
+rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+}
+rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
+stageNo: 0
+doInstrument: true
+nCrossLevelParams: 0
+commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+}
+cmdType: CMD_SELECT
diff --git a/depends/univplan/test/data/TestCompletedPlanBefore b/depends/univplan/test/data/TestCompletedPlanBefore
new file mode 100644
index 0000000..19e755e
--- /dev/null
+++ b/depends/univplan/test/data/TestCompletedPlanBefore
@@ -0,0 +1,628 @@
+plan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_AGG
+ agg {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_AGGREF
+ aggref {
+ transFuncId: 494
+ retType: 103
+ transInitVal: true
+ finalFuncId: 38324
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 65001
+ varAttNo: 1
+ typeId: 103
+ typeMod: -1
+ }
+ }
+ funcId: 492
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_AGG
+ agg {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_AGGREF
+ aggref {
+ transFuncId: 493
+ retType: 103
+ transInitVal: true
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 65001
+ varAttNo: 1
+ typeId: 103
+ typeMod: -1
+ }
+ }
+ funcId: 492
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 158
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 92
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 35
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_FUNCEXPR
+ funcexpr {
+ funcId: 0
+ retType: 300
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_BOOLEXPR
+ boolexpr {
+ args {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 164
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 14
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ type: BOOLEXPRTYPE_OR_EXPR
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ numGroups: 1000
+ groupColIndexes: 1
+ groupColIndexes: 3
+ }
+ }
+ }
+ type: CONNECTORTYPE_SHUFFLE
+ hashExpr {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 0
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ numGroups: 1000
+ groupColIndexes: 1
+ groupColIndexes: 3
+ }
+ }
+ planRows: 110
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "0"
+ typeMod: -1
+ }
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 339
+ retType: 103
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+ }
+ planRows: 110
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+}
+rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+}
+rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
+doInstrument: true
+commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+}
diff --git a/depends/univplan/test/data/TestLimitCount b/depends/univplan/test/data/TestLimitCount
new file mode 100644
index 0000000..56da317
--- /dev/null
+++ b/depends/univplan/test/data/TestLimitCount
@@ -0,0 +1,228 @@
+plan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ planRows: 9
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 339
+ retType: 103
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "-1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+ }
+ planRows: 9
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+}
diff --git a/depends/univplan/test/data/TestLimitCountOffset b/depends/univplan/test/data/TestLimitCountOffset
new file mode 100644
index 0000000..f1bebf4
--- /dev/null
+++ b/depends/univplan/test/data/TestLimitCountOffset
@@ -0,0 +1,246 @@
+plan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ planRows: 110
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "0"
+ typeMod: -1
+ }
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 339
+ retType: 103
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+ }
+ planRows: 110
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ limitCount {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+}
diff --git a/depends/univplan/test/data/TestLimitOffset b/depends/univplan/test/data/TestLimitOffset
new file mode 100644
index 0000000..dd7a801
--- /dev/null
+++ b/depends/univplan/test/data/TestLimitOffset
@@ -0,0 +1,212 @@
+plan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_LIMIT
+ limit {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ planRows: 99
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "0"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+ }
+ planRows: 99
+ planRowWidth: 0
+ operatorMemKB: 0
+ }
+ limitOffset {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 103
+ isNull: false
+ value: "100"
+ typeMod: -1
+ }
+ }
+ }
+}
diff --git a/depends/univplan/test/data/TestNullTest b/depends/univplan/test/data/TestNullTest
new file mode 100644
index 0000000..5f2e916
--- /dev/null
+++ b/depends/univplan/test/data/TestNullTest
@@ -0,0 +1,136 @@
+plan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_NULLTEST
+ nulltest {
+ arg {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ type: NULLTESTTYPE_IS_NOT_NULL
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+}
+rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+}
+rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
+commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+}
diff --git a/depends/univplan/test/data/TestQualListAndExpr b/depends/univplan/test/data/TestQualListAndExpr
new file mode 100644
index 0000000..27382a0
--- /dev/null
+++ b/depends/univplan/test/data/TestQualListAndExpr
@@ -0,0 +1,259 @@
+plan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 158
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 92
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 35
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_FUNCEXPR
+ funcexpr {
+ funcId: 0
+ retType: 300
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ }
+ }
+ qualList {
+ type: UNIVPLAN_EXPR_BOOLEXPR
+ boolexpr {
+ args {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 164
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "1"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_OPEXPR
+ opexpr {
+ funcId: 14
+ retType: 300
+ args {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 2
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ args {
+ type: UNIVPLAN_EXPR_CONST
+ val {
+ type: 102
+ isNull: false
+ value: "10"
+ typeMod: -1
+ }
+ }
+ }
+ }
+ type: BOOLEXPRTYPE_OR_EXPR
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+}
+rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+}
+rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
+commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+}
diff --git a/depends/univplan/test/data/TestSort b/depends/univplan/test/data/TestSort
new file mode 100644
index 0000000..0d2b6fd
--- /dev/null
+++ b/depends/univplan/test/data/TestSort
@@ -0,0 +1,99 @@
+plan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SORT
+ sort {
+ super {
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ colIdx: 1
+ colIdx: 2
+ sortFuncId: 21
+ sortFuncId: 14
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ colIdx: 1
+ colIdx: 2
+ sortFuncId: 21
+ sortFuncId: 14
+ }
+}
diff --git a/depends/univplan/test/data/TestStagizeAfter b/depends/univplan/test/data/TestStagizeAfter
new file mode 100644
index 0000000..1a8787a
--- /dev/null
+++ b/depends/univplan/test/data/TestStagizeAfter
@@ -0,0 +1,167 @@
+plan {
+ type: UNIVPLAN_SINK
+ sink {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ connectorType: CONNECTORTYPE_BROADCAST
+ sourceStageNo: 1
+ currentStageNo: 0
+ }
+}
+childStages {
+ plan {
+ type: UNIVPLAN_BROADCAST
+ broadcast {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ targetStageNo: 0
+ currentStageNo: 1
+ }
+ }
+ receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+ }
+ receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+ }
+ stageNo: 1
+ doInstrument: false
+ nCrossLevelParams: 0
+ cmdType: CMD_SELECT
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
+stageNo: 0
+doInstrument: false
+nCrossLevelParams: 0
+cmdType: CMD_SELECT
diff --git a/depends/univplan/test/data/TestStagizeBefore b/depends/univplan/test/data/TestStagizeBefore
new file mode 100644
index 0000000..50903ee
--- /dev/null
+++ b/depends/univplan/test/data/TestStagizeBefore
@@ -0,0 +1,100 @@
+plan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ type: CONNECTORTYPE_BROADCAST
+ }
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
diff --git a/depends/univplan/test/data/TestUnivPlanProtoGenerate b/depends/univplan/test/data/TestUnivPlanProtoGenerate
new file mode 100644
index 0000000..859d2ae
--- /dev/null
+++ b/depends/univplan/test/data/TestUnivPlanProtoGenerate
@@ -0,0 +1,130 @@
+plan {
+ type: UNIVPLAN_CONNECTOR
+ connector {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ leftPlan {
+ type: UNIVPLAN_SCAN_SEQ
+ scanSeq {
+ super {
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 1
+ typeId: 102
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ targetList {
+ type: UNIVPLAN_EXPR_TARGETENTRY
+ targetentry {
+ expression {
+ type: UNIVPLAN_EXPR_VAR
+ var {
+ varNo: 1
+ varAttNo: 3
+ typeId: 250
+ typeMod: -1
+ }
+ }
+ resJunk: false
+ }
+ }
+ }
+ relId: 1
+ tasks {
+ serializedSplits: "\000\000\001\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000/a\010\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\377\377\377\377"
+ }
+ tasks {
+ serializedSplits: "\000\000\002\000\000\000\005\000\000\000\000\000\000\000\370\372\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000/a/b\020\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\310\000\000\000\000\000\000\000d\000\000\000\000\000\000\000g\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377f\000\000\000\377\377\377\377\377\377\377\377\002\000\000\000\000\000\000\000\001\001\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\377\377\377\377\377\377\377\377"
+ }
+ columnsToRead: 0
+ columnsToRead: 1
+ }
+ }
+ }
+ type: CONNECTORTYPE_CONVERGE
+ }
+}
+rangeTables {
+ table {
+ tableId: 0
+ format: INVALID_FORMAT
+ location: ""
+ tableOptionsInJson: ""
+ }
+}
+rangeTables {
+ table {
+ tableId: 2
+ format: ORC_FORMAT
+ location: "/tmp"
+ tableOptionsInJson: "TableOptionsInJson_20"
+ columns {
+ columnName: "p1"
+ typeId: 102
+ typeMod: -1
+ }
+ columns {
+ columnName: "p2"
+ typeId: 250
+ typeMod: -1
+ }
+ }
+}
+receivers {
+ listener {
+ address: "mdw"
+ port: 101
+ }
+}
+receivers {
+ listener {
+ address: "smdw"
+ port: 201
+ }
+ listener {
+ address: "smdw"
+ port: 203
+ }
+}
+commonValue {
+ key: "TableOptionsInJson_20"
+ value: "option1 string in json"
+}
diff --git a/depends/univplan/test/parallel/parallel-launcher.py b/depends/univplan/test/parallel/parallel-launcher.py
new file mode 100755
index 0000000..f572f7b
--- /dev/null
+++ b/depends/univplan/test/parallel/parallel-launcher.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python
+# Copyright (c) 2010 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+This tool launches several shards of a gtest-based binary
+in parallel on a local machine.
+
+Example usage:
+
+parallel_launcher.py path/to/base_unittests
+"""
+
+import optparse
+import os
+import subprocess
+import sys
+import threading
+import time
+
+
+def StreamCopyWindows(stream_from, stream_to):
+ """Copies stream_from to stream_to."""
+
+ while True:
+ buf = stream_from.read(1024)
+ if not buf:
+ break
+ stream_to.write(buf)
+ stream_to.flush()
+
+def StreamCopyPosix(stream_from, stream_to, child_exited):
+ """
+ Copies stream_from to stream_to, and exits if child_exited
+ is signaled.
+ """
+
+ import fcntl
+
+ # Put the source stream in a non-blocking mode, so we can check
+ # child_exited when there is no data.
+ fd = stream_from.fileno()
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
+
+ while True:
+ try:
+ buf = os.read(fd, 1024)
+ except OSError, e:
+ if e.errno == 11 or e.errno == 35:
+ if child_exited.isSet():
+ break
+ time.sleep(0.1)
+ continue
+ raise
+ if not buf:
+ break
+ stream_to.write(buf)
+ stream_to.flush()
+
+class TestLauncher(object):
+ def __init__(self, args, executable, num_shards, shard):
+ self._args = args
+ self._executable = executable
+ self._num_shards = num_shards
+ self._shard = shard
+ self._test = None
+
+ def launch(self):
+ env = os.environ.copy()
+
+ env['CHROME_LOG_FILE'] = 'chrome_log_%d' % self._shard
+
+ if 'GTEST_TOTAL_SHARDS' in env:
+ # Handle the requested sharding transparently.
+ outer_shards = int(env['GTEST_TOTAL_SHARDS'])
+ outer_index = int(env['GTEST_SHARD_INDEX'])
+
+ env['GTEST_TOTAL_SHARDS'] = str(self._num_shards * outer_shards)
+
+ # Calculate the right shard index to pass to the child. This is going
+ # to be a shard of a shard.
+ env['GTEST_SHARD_INDEX'] = str((self._num_shards * outer_index) +
+ self._shard)
+ else:
+ env['GTEST_TOTAL_SHARDS'] = str(self._num_shards)
+ env['GTEST_SHARD_INDEX'] = str(self._shard)
+
+ args = self._args + ['--test-server-shard=' + str(self._shard)]
+
+ self._test = subprocess.Popen(args=args,
+ executable=self._executable,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ env=env)
+ def wait(self):
+ if subprocess.mswindows:
+ stdout_thread = threading.Thread(
+ target=StreamCopyWindows,
+ args=[self._test.stdout, sys.stdout])
+ stdout_thread.start()
+ code = self._test.wait()
+ stdout_thread.join()
+ return code
+ else:
+ child_exited = threading.Event()
+ stdout_thread = threading.Thread(
+ target=StreamCopyPosix,
+ args=[self._test.stdout, sys.stdout, child_exited])
+ stdout_thread.start()
+ code = self._test.wait()
+ child_exited.set()
+ stdout_thread.join()
+ return code
+
+def main(argv):
+ parser = optparse.OptionParser()
+ parser.add_option("--shards", type="int", dest="shards", default=16)
+
+ # Make it possible to pass options to the launched process.
+ # Options for parallel_launcher should be first, then the binary path,
+ # and finally - optional arguments for the launched binary.
+ parser.disable_interspersed_args()
+
+ options, args = parser.parse_args(argv)
+
+ if not args:
+ print 'You must provide path to the test binary'
+ return 1
+
+ env = os.environ
+ if bool('GTEST_TOTAL_SHARDS' in env) != bool('GTEST_SHARD_INDEX' in env):
+ print 'Inconsistent environment. GTEST_TOTAL_SHARDS and GTEST_SHARD_INDEX'
+ print 'should either be both defined, or both undefined.'
+ return 1
+
+ launchers = []
+
+ for shard in range(options.shards):
+ launcher = TestLauncher(args, args[0], options.shards, shard)
+ launcher.launch()
+ launchers.append(launcher)
+
+ return_code = 0
+ for launcher in launchers:
+ if launcher.wait() != 0:
+ return_code = 1
+
+ return return_code
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/depends/univplan/test/unit/CMakeLists.txt b/depends/univplan/test/unit/CMakeLists.txt
new file mode 100644
index 0000000..2eebc74
--- /dev/null
+++ b/depends/univplan/test/unit/CMakeLists.txt
@@ -0,0 +1,14 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+AUTO_SOURCES(unit_SOURCES "*.cc" "RECURSE" ${CMAKE_CURRENT_SOURCE_DIR})
+
+FIND_PACKAGE(GTest REQUIRED)
+
+INCLUDE_DIRECTORIES(${univplan_ROOT_DIR}/test/unit)
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+
+ADD_EXECUTABLE(unit EXCLUDE_FROM_ALL
+ ${unit_SOURCES}
+)
+
+target_link_libraries(unit ${CLANG_LDFLAGS} univplan-shared gtest gmock)
diff --git a/depends/univplan/test/unit/test-basic-univplan.cc b/depends/univplan/test/unit/test-basic-univplan.cc
new file mode 100644
index 0000000..50caf34
--- /dev/null
+++ b/depends/univplan/test/unit/test-basic-univplan.cc
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "./test-univplan.h"
+
+#include <errno.h>
+
+#include "gtest/gtest.h"
+
+#include "dbcommon/log/exception.h"
+#include "dbcommon/log/logger.h"
+
+#include "univplan/common/plannode-util.h"
+#include "univplan/common/stagize.h"
+#include "univplan/common/var-util.h"
+#include "univplan/cwrapper/univplan-c.h"
+#include "univplan/testutil/univplan-proto-util.h"
+#include "univplan/univplanbuilder/univplanbuilder-expr-tree.h"
+#include "univplan/univplanbuilder/univplanbuilder-plan.h"
+#include "univplan/univplanbuilder/univplanbuilder-table.h"
+#include "univplan/univplanbuilder/univplanbuilder.h"
+
+namespace univplan {
+
+TEST(TestBasicUnivPlan, TestBasicUnivPlan) {
+ univplan::UnivPlanBuilder upb;
+ univplan::UnivPlanBuilderAgg *aggb;
+
+ univplan::UnivPlanBuilderNode::uptr aggb1 =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_AGG);
+ aggb = dynamic_cast<univplan::UnivPlanBuilderAgg *>(aggb1.get());
+
+ aggb->setNumGroups(0);
+ aggb->uid = 1;
+ aggb->pid = -1;
+
+ univplan::UnivPlanBuilderNode::uptr aggb2 =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_AGG);
+ aggb = dynamic_cast<univplan::UnivPlanBuilderAgg *>(aggb2.get());
+ aggb->setNumGroups(0);
+ aggb->uid = 2;
+ aggb->pid = 1;
+
+ univplan::UnivPlanBuilderNode::uptr aggb3 =
+ univplan::PlanNodeUtil::createPlanBuilderNode(univplan::UNIVPLAN_AGG);
+ aggb = dynamic_cast<univplan::UnivPlanBuilderAgg *>(aggb3.get());
+ aggb->setNumGroups(0);
+ aggb->uid = 3;
+ aggb->pid = 1;
+
+ upb.addPlanNode(true, std::move(aggb1));
+ upb.addPlanNode(true, std::move(aggb2));
+ upb.addPlanNode(false, std::move(aggb3));
+
+ UnivPlanPlan plan;
+ plan.ParseFromString(upb.serialize());
+ EXPECT_STREQ(upb.getJsonFormatedPlan().c_str(), plan.DebugString().c_str());
+}
+
+TEST(TestBasicUnivPlan, TestUnivPlanProtoGenerate) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, false, 0);
+ upu.constructRangeTable();
+ upu.constructReceiver();
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestUnivPlanProtoGenerate", jsonFormatPlan);
+ plan.readFromFile("TestUnivPlanProtoGenerate");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestLimitCountOffset) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructLimitTop(-1, 10, 100);
+ int32_t uid2 = upu.constructConnector(uid1, 2, false);
+ int32_t uid3 = upu.constructLimitBelow(uid2, 10, 100);
+ int32_t uid4 = upu.constructSeqScan(uid3, false, 0);
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestLimitCountOffset", jsonFormatPlan);
+ plan.readFromFile("TestLimitCountOffset");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestLimitCount) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructLimitTop(-1, 10, -1);
+ int32_t uid2 = upu.constructConnector(uid1, 2, false);
+ int32_t uid3 = upu.constructLimitBelow(uid2, 10, -1);
+ int32_t uid4 = upu.constructSeqScan(uid3, false, 0);
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestLimitCount", jsonFormatPlan);
+ plan.readFromFile("TestLimitCount");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestLimitOffset) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructLimitTop(-1, -1, 100);
+ int32_t uid2 = upu.constructConnector(uid1, 2, false);
+ int32_t uid3 = upu.constructLimitBelow(uid2, -1, 100);
+ int32_t uid4 = upu.constructSeqScan(uid3, false, 0);
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestLimitOffset", jsonFormatPlan);
+ plan.readFromFile("TestLimitOffset");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestAgg) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructAgg(uid1, 3);
+ int32_t uid3 = upu.constructConnector(uid2, 0, false);
+ int32_t uid4 = upu.constructAgg(uid3, 1);
+ int32_t uid5 = upu.constructSeqScan(uid4, false, 0);
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestAgg", jsonFormatPlan);
+ plan.readFromFile("TestAgg");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestSort) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructSortConnector(-1, 2);
+ int32_t uid2 = upu.constructSort(uid1);
+ int32_t uid3 = upu.constructSeqScan(uid2, false, 0);
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestSort", jsonFormatPlan);
+ plan.readFromFile("TestSort");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestQualListAndExpr) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, true, 0);
+ upu.constructRangeTable();
+ upu.constructReceiver();
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestQualListAndExpr", jsonFormatPlan);
+ plan.readFromFile("TestQualListAndExpr");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestBasicUnivPlan, TestNullTest) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, false, 2);
+ upu.constructRangeTable();
+ upu.constructReceiver();
+ const char *jsonFormatPlan = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestNullTest", jsonFormatPlan);
+ plan.readFromFile("TestNullTest");
+ const char *expecedPlan = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan, jsonFormatPlan);
+}
+
+TEST(TestUnivPlan, TestCommonValue) {
+ univplan::UnivPlanBuilder upb;
+ upb.getPlanBuilderPlan()->addCommonValue("abc", "value", nullptr);
+ EXPECT_EQ(1, upb.getPlanBuilderPlan()->getPlan()->commonvalue().size());
+
+ for (auto i = upb.getPlanBuilderPlan()->getPlan()->commonvalue().begin();
+ i != upb.getPlanBuilderPlan()->getPlan()->commonvalue().end(); ++i) {
+ LOG_INFO("key %s value %s", i->first.c_str(), i->second.c_str());
+ }
+
+ std::string fetch1 =
+ upb.getPlanBuilderPlan()->getPlan()->commonvalue().find("abc")->second;
+ LOG_INFO("pass 1");
+
+ EXPECT_STREQ("value", fetch1.c_str());
+ // add duplicate key when having no new key referenced, in this case, should
+ // have old value overwrited
+ upb.getPlanBuilderPlan()->addCommonValue("abc", "value2", nullptr);
+ fetch1 = upb.getPlanBuilderPlan()->getPlan()->commonvalue().at("abc");
+ EXPECT_STREQ("value2", fetch1.c_str());
+ LOG_INFO("pass 2");
+ // pass new key reference, duplicate key will cause new key generated
+ std::string nkey1, nkey2;
+ upb.getPlanBuilderPlan()->addCommonValue("dupkey1", "value1", &nkey1);
+ fetch1 = upb.getPlanBuilderPlan()->getPlan()->commonvalue().at(nkey1);
+ EXPECT_STREQ("value1", fetch1.c_str());
+ LOG_INFO("pass 3");
+ upb.getPlanBuilderPlan()->addCommonValue("dupkey1", "value2", &nkey2);
+ fetch1 = upb.getPlanBuilderPlan()->getPlan()->commonvalue().at(nkey2);
+ EXPECT_STREQ("value2", fetch1.c_str());
+ EXPECT_STRNE(nkey1.c_str(), nkey2.c_str());
+ LOG_INFO("pass 4");
+ // passing duplicate key and its value, there should cause nothing updated
+ upb.getPlanBuilderPlan()->addCommonValue("dupkey1", "value1", &nkey1);
+ EXPECT_STREQ("dupkey10", nkey1.c_str());
+ LOG_INFO("pass 5");
+}
+
+/*
+ * SELECT count(int1), text from test2 where int1 > 1 or int2 < 10 and random()
+ * < int1 group by int1, text limit 10 offset 100;
+ */
+TEST(TestUnivPlanCWrapper, TestCompletedPlan) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructLimitTop(-1, 10, 100);
+ int32_t uid2 = upu.constructConnector(uid1, 2, true);
+ int32_t uid3 = upu.constructLimitBelow(uid2, 10, 100);
+ int32_t uid4 = upu.constructAgg(uid3, 3);
+ int32_t uid5 = upu.constructConnector(uid4, 0, true);
+ int32_t uid6 = upu.constructAgg(uid5, 1);
+ int32_t uid7 = upu.constructSeqScan(uid6, true, 0);
+ upu.constructRangeTable();
+ upu.univPlanSetDoInstrument(true);
+ upu.constructReceiver();
+
+ const char *jsonFormatPlan1 = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestCompletedPlanBefore", jsonFormatPlan1);
+ plan.readFromFile("TestCompletedPlanBefore");
+ const char *expecedPlan1 = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan1, jsonFormatPlan1);
+
+ upu.univPlanStagize();
+
+ const char *jsonFormatPlan2 = upu.univPlanGetJsonFormatedPlan();
+ // plan.writeIntoFile("TestCompletedPlanAfter", jsonFormatPlan2);
+ plan.readFromFile("TestCompletedPlanAfter");
+ const char *expecedPlan2 = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan2, jsonFormatPlan2);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/test/unit/test-minmax-cotasklist.cc b/depends/univplan/test/unit/test-minmax-cotasklist.cc
new file mode 100644
index 0000000..424143e
--- /dev/null
+++ b/depends/univplan/test/unit/test-minmax-cotasklist.cc
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <errno.h>
+
+#include "gtest/gtest.h"
+
+#include "dbcommon/log/exception.h"
+#include "dbcommon/log/logger.h"
+
+#include "univplan/minmax/minmax-predicates.h"
+
+namespace univplan {
+//-----------------------------------------------------------------------------
+// 1 source task covers target task first half
+//-----------------------------------------------------------------------------
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect11) {
+ // task [[ ]]
+ // src [[ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 1024, 128, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(1024, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect12) {
+ // task [[ ]]
+ // src [[ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 1024, 228, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(327, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect13) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 1024, 512, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(512, task1.taskBeginRowId);
+ EXPECT_EQ(611, task1.getTaskEndRowId());
+}
+
+//-----------------------------------------------------------------------------
+// 2 source task covers target task completely
+//-----------------------------------------------------------------------------
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect21) {
+ // task [[ ]]
+ // src [[ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 128, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(0, task1.taskRowCount);
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect22) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 128, 256);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(383, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect23) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 512, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(512, task1.taskBeginRowId);
+ EXPECT_EQ(611, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect24) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 1024, 512);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(1024, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect25) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 1536, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(0, task1.taskRowCount);
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect26) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 128, 1536);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+//-----------------------------------------------------------------------------
+// 3 source task covers target task second half
+//-----------------------------------------------------------------------------
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect31) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 512, 2048, 513, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(513, task1.taskBeginRowId);
+ EXPECT_EQ(612, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect32) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 512, 2048, 513, 1024);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(513, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect33) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048, 1536, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(0, task1.taskRowCount);
+}
+
+//-----------------------------------------------------------------------------
+// 4 target task covers source task
+//-----------------------------------------------------------------------------
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect41) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 512, 512, 520, 100);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(520, task1.taskBeginRowId);
+ EXPECT_EQ(619, task1.getTaskEndRowId());
+}
+
+//----------------------------------------
+// 5 second source task after intersected
+//----------------------------------------
+
+TEST(TestMinMaxCOBlockTask, BasicIntersect51) {
+ // task [[ ]]
+ // src [ [ ] ][[ ]]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 512, 512, 520, 100);
+ COBlockTask tasksrc2(1280, 1024, 512);
+ task1.resetIntersection();
+ task1.intersect(tasksrc);
+ EXPECT_EQ(520, task1.taskBeginRowId);
+ EXPECT_EQ(619, task1.getTaskEndRowId());
+ task1.intersect(tasksrc2);
+ EXPECT_EQ(520, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicUnionAll11) {
+ // task [[ ]]
+ // src [[ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 1024, 128, 100);
+ task1.resetUnionAll();
+ task1.unionAll(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicUnionAll12) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 1024, 128, 512);
+ task1.resetUnionAll();
+ task1.unionAll(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicUnionAll13) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 2048);
+ COBlockTask tasksrc(256, 512, 512);
+ task1.resetUnionAll();
+ task1.unionAll(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(2303, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicUnionAll14) {
+ // task [[ ]]
+ // src [ [ ] ]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 1024, 512);
+ task1.resetUnionAll();
+ task1.unionAll(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+
+TEST(TestMinMaxCOBlockTask, BasicUnionAll21) {
+ // task [[ ]]
+ // src [[ ]]
+ COBlockTask task1(1024, 256, 1024);
+ COBlockTask tasksrc(256, 0, 2048);
+ task1.resetUnionAll();
+ task1.unionAll(tasksrc);
+ EXPECT_EQ(256, task1.taskBeginRowId);
+ EXPECT_EQ(1279, task1.getTaskEndRowId());
+}
+} // namespace univplan
diff --git a/depends/univplan/test/unit/test-univplan-cwrapper.cc b/depends/univplan/test/unit/test-univplan-cwrapper.cc
new file mode 100644
index 0000000..45a7b81
--- /dev/null
+++ b/depends/univplan/test/unit/test-univplan-cwrapper.cc
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "./test-univplan.h"
+
+#include <errno.h>
+
+#include "gtest/gtest.h"
+
+#include "dbcommon/log/exception.h"
+#include "dbcommon/log/logger.h"
+#include "dbcommon/type/type-kind.h"
+
+#include "univplan/cwrapper/univplan-c.h"
+#include "univplan/testutil/univplan-proto-util.h"
+#include "univplan/univplanbuilder/univplanbuilder.h"
+
+namespace univplan {
+
+TEST(TestUnivPlanCWrapper, TestUnivPlanVarutil) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, false, 0);
+ upu.constructRangeTable();
+ upu.constructReceiver();
+ upu.univPlanFixVarType();
+}
+
+TEST(TestUnivPlanCWrapper, TestStagize) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 1, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, false, 0);
+ upu.constructReceiver();
+
+ const char *jsonFormatPlan1 = upu.univPlanGetJsonFormatedPlan();
+ UnivPlanPlanString plan;
+ // plan.writeIntoFile("TestStagizeBefore", jsonFormatPlan1);
+ plan.readFromFile("TestStagizeBefore");
+ // puts("--TestStagizeBefore--");
+ // puts(jsonFormatPlan1);
+ const char *expecedPlan1 = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan1, jsonFormatPlan1);
+
+ upu.univPlanStagize();
+
+ const char *jsonFormatPlan2 = upu.univPlanGetJsonFormatedPlan();
+ // plan.writeIntoFile("TestStagizeAfter", jsonFormatPlan2);
+ plan.readFromFile("TestStagizeAfter");
+ // puts("--TestStagizeAfter--");
+ // puts(jsonFormatPlan2);
+ const char *expecedPlan2 = plan.getPlanString();
+ EXPECT_STREQ(expecedPlan2, jsonFormatPlan2);
+}
+
+TEST(TestUnivPlanCWrapper, TestSerialize) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, false, 0);
+ upu.constructRangeTable();
+ upu.constructReceiver();
+ int32_t len;
+ upu.univPlanSerialize(&len);
+ EXPECT_EQ(406, len);
+}
+
+TEST(TestUnivPlanCWrapper, TestSetDoInstrument) {
+ UnivPlanProtoUtility upu;
+ int32_t uid1 = upu.constructConnector(-1, 2, false);
+ int32_t uid2 = upu.constructSeqScan(uid1, false, 0);
+ upu.constructRangeTable();
+ upu.univPlanSetDoInstrument(true);
+}
+
+} // namespace univplan
diff --git a/depends/univplan/test/unit/test-univplan.h b/depends/univplan/test/unit/test-univplan.h
new file mode 100644
index 0000000..bbc3fe2
--- /dev/null
+++ b/depends/univplan/test/unit/test-univplan.h
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef UNIVPLAN_TEST_UNIT_TEST_UNIVPLAN_H_
+#define UNIVPLAN_TEST_UNIT_TEST_UNIVPLAN_H_
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "gtest/gtest.h"
+
+namespace univplan {
+class UnivPlanPlanString {
+ public:
+ UnivPlanPlanString() {}
+ ~UnivPlanPlanString() { planString.clear(); }
+
+ void readFromFile(const char *fileName) {
+ std::ifstream in;
+ std::string filePath(DATA_DIR);
+ filePath.append(fileName);
+ in.open(filePath);
+ ASSERT_TRUE(!!in);
+ std::string str;
+ planString.clear();
+ while (getline(in, str)) {
+ planString.append(str);
+ planString.append("\n");
+ }
+ in.close();
+ }
+
+ // only used for creating univplan ans file
+ void writeIntoFile(const char *fileName, const char *str) {
+ std::ofstream out;
+ std::string filePath(DATA_DIR);
+ filePath.append(fileName);
+ out.open(filePath);
+ out << str;
+ out.close();
+ }
+
+ const char *getPlanString() { return planString.c_str(); }
+
+ private:
+ std::string planString;
+};
+} // namespace univplan
+#endif // UNIVPLAN_TEST_UNIT_TEST_UNIVPLAN_H_
diff --git a/depends/univplan/test/unit/unit-test-main.cc b/depends/univplan/test/unit/unit-test-main.cc
new file mode 100644
index 0000000..970802f
--- /dev/null
+++ b/depends/univplan/test/unit/unit-test-main.cc
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "gtest/gtest.h"
+
+#include "dbcommon/log/logger.h"
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+#ifdef TEST_ROOT_DIRECTORY
+ chdir(TEST_ROOT_DIRECTORY);
+#endif
+
+ return RUN_ALL_TESTS();
+}