Merge branch 'develop' into feature/TD-4399
This commit is contained in:
commit
f603458a5e
|
@ -10,3 +10,6 @@
|
||||||
[submodule "tests/examples/rust"]
|
[submodule "tests/examples/rust"]
|
||||||
path = tests/examples/rust
|
path = tests/examples/rust
|
||||||
url = https://github.com/songtianyi/tdengine-rust-bindings.git
|
url = https://github.com/songtianyi/tdengine-rust-bindings.git
|
||||||
|
[submodule "deps/jemalloc"]
|
||||||
|
path = deps/jemalloc
|
||||||
|
url = https://github.com/jemalloc/jemalloc
|
||||||
|
|
|
@ -59,6 +59,11 @@ IF (TD_LINUX_64)
|
||||||
MESSAGE(STATUS "linux64 is defined")
|
MESSAGE(STATUS "linux64 is defined")
|
||||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -fPIC -gdwarf-2 -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||||
|
|
||||||
|
IF (JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX_32)
|
IF (TD_LINUX_32)
|
||||||
|
|
|
@ -72,3 +72,8 @@ IF (${RANDOM_NETWORK_FAIL} MATCHES "true")
|
||||||
SET(TD_RANDOM_NETWORK_FAIL TRUE)
|
SET(TD_RANDOM_NETWORK_FAIL TRUE)
|
||||||
MESSAGE(STATUS "build with random-network-fail enabled")
|
MESSAGE(STATUS "build with random-network-fail enabled")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (${JEMALLOC_ENABLED} MATCHES "true")
|
||||||
|
SET(TD_JEMALLOC_ENABLED TRUE)
|
||||||
|
MESSAGE(STATUS "build with jemalloc enabled")
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -18,3 +18,16 @@ ENDIF ()
|
||||||
IF (TD_DARWIN AND TD_MQTT)
|
IF (TD_DARWIN AND TD_MQTT)
|
||||||
ADD_SUBDIRECTORY(MQTT-C)
|
ADD_SUBDIRECTORY(MQTT-C)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
MESSAGE("setup dpes/jemalloc, current source dir:" ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
MESSAGE("binary dir:" ${CMAKE_BINARY_DIR})
|
||||||
|
include(ExternalProject)
|
||||||
|
ExternalProject_Add(jemalloc
|
||||||
|
PREFIX "jemalloc"
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jemalloc
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
CONFIGURE_COMMAND ./autogen.sh COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/build/
|
||||||
|
BUILD_COMMAND ${MAKE}
|
||||||
|
)
|
||||||
|
ENDIF ()
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ea6b3e973b477b8061e0076bb257dbd7f3faa756
|
|
@ -67,7 +67,41 @@ fi
|
||||||
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
||||||
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/go ${pkg_dir}${install_home_path}/connector
|
||||||
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
cp -r ${top_dir}/src/connector/nodejs ${pkg_dir}${install_home_path}/connector
|
||||||
cp ${compile_dir}/build/lib/taos-jdbcdriver*dist.* ${pkg_dir}${install_home_path}/connector ||:
|
cp ${compile_dir}/build/lib/taos-jdbcdriver*.* ${pkg_dir}${install_home_path}/connector ||:
|
||||||
|
|
||||||
|
if [ -f ${compile_dir}/build/bin/jemalloc-config ]; then
|
||||||
|
install_user_local_path="/usr/local"
|
||||||
|
mkdir -p ${pkg_dir}${install_user_local_path}/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3}
|
||||||
|
cp ${compile_dir}/build/bin/jemalloc-config ${pkg_dir}${install_user_local_path}/bin/
|
||||||
|
if [ -f ${compile_dir}/build/bin/jemalloc.sh ]; then
|
||||||
|
cp ${compile_dir}/build/bin/jemalloc.sh ${pkg_dir}${install_user_local_path}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/bin/jeprof ]; then
|
||||||
|
cp ${compile_dir}/build/bin/jeprof ${pkg_dir}${install_user_local_path}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp ${compile_dir}/build/include/jemalloc/jemalloc.h ${pkg_dir}${install_user_local_path}/include/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp ${compile_dir}/build/lib/libjemalloc.so.2 ${pkg_dir}${install_user_local_path}/lib/
|
||||||
|
ln -sf libjemalloc.so.2 ${pkg_dir}${install_user_local_path}/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/libjemalloc.a ]; then
|
||||||
|
cp ${compile_dir}/build/lib/libjemalloc.a ${pkg_dir}${install_user_local_path}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp ${compile_dir}/build/lib/libjemalloc_pic.a ${pkg_dir}${install_user_local_path}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp ${compile_dir}/build/lib/pkgconfig/jemalloc.pc ${pkg_dir}${install_user_local_path}/lib/pkgconfig/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp ${compile_dir}/build/share/doc/jemalloc/jemalloc.html ${pkg_dir}${install_user_local_path}/share/doc/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f ${compile_dir}/build/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp ${compile_dir}/build/share/man/man3/jemalloc.3 ${pkg_dir}${install_user_local_path}/share/man/man3/
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
cp -r ${compile_dir}/../packaging/deb/DEBIAN ${pkg_dir}/
|
cp -r ${compile_dir}/../packaging/deb/DEBIAN ${pkg_dir}/
|
||||||
chmod 755 ${pkg_dir}/DEBIAN/*
|
chmod 755 ${pkg_dir}/DEBIAN/*
|
||||||
|
|
|
@ -22,11 +22,12 @@ cpuType=x64 # [aarch32 | aarch64 | x64 | x86 | mips64 ...]
|
||||||
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...]
|
osType=Linux # [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...]
|
||||||
pagMode=full # [full | lite]
|
pagMode=full # [full | lite]
|
||||||
soMode=dynamic # [static | dynamic]
|
soMode=dynamic # [static | dynamic]
|
||||||
|
allocator=glibc # [glibc | jemalloc]
|
||||||
dbName=taos # [taos | power]
|
dbName=taos # [taos | power]
|
||||||
verNumber=""
|
verNumber=""
|
||||||
verNumberComp="2.0.0.0"
|
verNumberComp="2.0.0.0"
|
||||||
|
|
||||||
while getopts "hv:V:c:o:l:s:d:n:m:" arg
|
while getopts "hv:V:c:o:l:s:d:a:n:m:" arg
|
||||||
do
|
do
|
||||||
case $arg in
|
case $arg in
|
||||||
v)
|
v)
|
||||||
|
@ -53,6 +54,10 @@ do
|
||||||
#echo "dbName=$OPTARG"
|
#echo "dbName=$OPTARG"
|
||||||
dbName=$(echo $OPTARG)
|
dbName=$(echo $OPTARG)
|
||||||
;;
|
;;
|
||||||
|
a)
|
||||||
|
#echo "allocator=$OPTARG"
|
||||||
|
allocator=$(echo $OPTARG)
|
||||||
|
;;
|
||||||
n)
|
n)
|
||||||
#echo "verNumber=$OPTARG"
|
#echo "verNumber=$OPTARG"
|
||||||
verNumber=$(echo $OPTARG)
|
verNumber=$(echo $OPTARG)
|
||||||
|
@ -71,6 +76,7 @@ do
|
||||||
echo " -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] "
|
echo " -o [Linux | Kylin | Alpine | Raspberrypi | Darwin | Windows | Ningsi60 | Ningsi80 |...] "
|
||||||
echo " -V [stable | beta] "
|
echo " -V [stable | beta] "
|
||||||
echo " -l [full | lite] "
|
echo " -l [full | lite] "
|
||||||
|
echo " -a [glibc | jemalloc] "
|
||||||
echo " -s [static | dynamic] "
|
echo " -s [static | dynamic] "
|
||||||
echo " -d [taos | power] "
|
echo " -d [taos | power] "
|
||||||
echo " -n [version number] "
|
echo " -n [version number] "
|
||||||
|
@ -84,7 +90,7 @@ do
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} soMode=${soMode} dbName=${dbName} verNumber=${verNumber} verNumberComp=${verNumberComp}"
|
echo "verMode=${verMode} verType=${verType} cpuType=${cpuType} osType=${osType} pagMode=${pagMode} soMode=${soMode} dbName=${dbName} allocator=${allocator} verNumber=${verNumber} verNumberComp=${verNumberComp}"
|
||||||
|
|
||||||
curr_dir=$(pwd)
|
curr_dir=$(pwd)
|
||||||
|
|
||||||
|
@ -180,12 +186,18 @@ else
|
||||||
fi
|
fi
|
||||||
cd ${compile_dir}
|
cd ${compile_dir}
|
||||||
|
|
||||||
|
if [[ "$allocator" == "jemalloc" ]]; then
|
||||||
|
allocator_macro="-DJEMALLOC_ENABLED=true"
|
||||||
|
else
|
||||||
|
allocator_macro=""
|
||||||
|
fi
|
||||||
|
|
||||||
# check support cpu type
|
# check support cpu type
|
||||||
if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then
|
if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" == "aarch32" ]] || [[ "$cpuType" == "mips64" ]] ; then
|
||||||
if [ "$verMode" != "cluster" ]; then
|
if [ "$verMode" != "cluster" ]; then
|
||||||
cmake ../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DPAGMODE=${pagMode}
|
cmake ../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DPAGMODE=${pagMode} ${allocator_macro}
|
||||||
else
|
else
|
||||||
cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp}
|
cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} ${allocator_macro}
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "input cpuType=${cpuType} error!!!"
|
echo "input cpuType=${cpuType} error!!!"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
%define homepath /usr/local/taos
|
%define homepath /usr/local/taos
|
||||||
|
%define userlocalpath /usr/local
|
||||||
%define cfg_install_dir /etc/taos
|
%define cfg_install_dir /etc/taos
|
||||||
%define __strip /bin/true
|
%define __strip /bin/true
|
||||||
|
|
||||||
|
@ -75,9 +76,53 @@ fi
|
||||||
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||||
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
||||||
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
cp -r %{_compiledir}/../src/connector/nodejs %{buildroot}%{homepath}/connector
|
||||||
cp %{_compiledir}/build/lib/taos-jdbcdriver*dist.* %{buildroot}%{homepath}/connector ||:
|
cp %{_compiledir}/build/lib/taos-jdbcdriver*.* %{buildroot}%{homepath}/connector ||:
|
||||||
cp -r %{_compiledir}/../tests/examples/* %{buildroot}%{homepath}/examples
|
cp -r %{_compiledir}/../tests/examples/* %{buildroot}%{homepath}/examples
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f %{_compiledir}/build/bin/jemalloc-config ]; then
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/bin
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/lib
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/lib/pkgconfig
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/include
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/include/jemalloc
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/doc
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/doc/jemalloc
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/man
|
||||||
|
mkdir -p %{buildroot}%{userlocalpath}/share/man/man3
|
||||||
|
|
||||||
|
cp %{_compiledir}/build/bin/jemalloc-config %{buildroot}%{userlocalpath}/bin/
|
||||||
|
if [ -f %{_compiledir}/build/bin/jemalloc.sh ]; then
|
||||||
|
cp %{_compiledir}/build/bin/jemalloc.sh %{buildroot}%{userlocalpath}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/bin/jeprof ]; then
|
||||||
|
cp %{_compiledir}/build/bin/jeprof %{buildroot}%{userlocalpath}/bin/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp %{_compiledir}/build/include/jemalloc/jemalloc.h %{buildroot}%{userlocalpath}/include/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp %{_compiledir}/build/lib/libjemalloc.so.2 %{buildroot}%{userlocalpath}/lib/
|
||||||
|
ln -sf libjemalloc.so.2 %{buildroot}%{userlocalpath}/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/libjemalloc.a ]; then
|
||||||
|
cp %{_compiledir}/build/lib/libjemalloc.a %{buildroot}%{userlocalpath}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp %{_compiledir}/build/lib/libjemalloc_pic.a %{buildroot}%{userlocalpath}/lib/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp %{_compiledir}/build/lib/pkgconfig/jemalloc.pc %{buildroot}%{userlocalpath}/lib/pkgconfig/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp %{_compiledir}/build/share/doc/jemalloc/jemalloc.html %{buildroot}%{userlocalpath}/share/doc/jemalloc/
|
||||||
|
fi
|
||||||
|
if [ -f %{_compiledir}/build/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp %{_compiledir}/build/share/man/man3/jemalloc.3 %{buildroot}%{userlocalpath}/share/man/man3/
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
#Scripts executed before installation
|
#Scripts executed before installation
|
||||||
%pre
|
%pre
|
||||||
csudo=""
|
csudo=""
|
||||||
|
|
|
@ -227,6 +227,52 @@ function install_lib() {
|
||||||
${csudo} ldconfig
|
${csudo} ldconfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function install_jemalloc() {
|
||||||
|
jemalloc_dir=${script_dir}/jemalloc
|
||||||
|
|
||||||
|
if [ -d ${jemalloc_dir} ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/bin
|
||||||
|
|
||||||
|
if [ -f ${jemalloc_dir}/bin/jemalloc-config ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc-config /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/bin/jemalloc.sh ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jemalloc.sh /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/bin/jeprof ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/bin/jeprof /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/include/jemalloc/jemalloc.h ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/include/jemalloc
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/include/jemalloc/jemalloc.h /usr/local/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc.so.2 ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/lib
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.so.2 /usr/local/lib
|
||||||
|
${csudo} ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/lib
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc.a ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
${csudo} /usr/bin/install -c -m 755 ${jemalloc_dir}/lib/libjemalloc_pic.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/lib/pkgconfig
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/share/doc/jemalloc
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${jemalloc_dir}/share/man/man3/jemalloc.3 ]; then
|
||||||
|
${csudo} /usr/bin/install -c -d /usr/local/share/man/man3
|
||||||
|
${csudo} /usr/bin/install -c -m 644 ${jemalloc_dir}/share/man/man3/jemalloc.3 /usr/local/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function install_header() {
|
function install_header() {
|
||||||
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
||||||
${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
||||||
|
@ -776,6 +822,7 @@ function update_TDengine() {
|
||||||
install_log
|
install_log
|
||||||
install_header
|
install_header
|
||||||
install_lib
|
install_lib
|
||||||
|
install_jemalloc
|
||||||
if [ "$pagMode" != "lite" ]; then
|
if [ "$pagMode" != "lite" ]; then
|
||||||
install_connector
|
install_connector
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
set -e
|
set -e
|
||||||
# set -x
|
# set -x
|
||||||
|
|
||||||
# -----------------------Variables definition---------------------
|
# -----------------------Variables definition
|
||||||
source_dir=$1
|
source_dir=$1
|
||||||
binary_dir=$2
|
binary_dir=$2
|
||||||
osType=$3
|
osType=$3
|
||||||
|
@ -176,6 +176,49 @@ function install_bin() {
|
||||||
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || :
|
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || :
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
function install_jemalloc() {
|
||||||
|
if [ "$osType" != "Darwin" ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/bin
|
||||||
|
|
||||||
|
if [ -f ${binary_dir}/build/bin/jemalloc-config ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc-config /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/bin/jemalloc.sh ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc.sh /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/bin/jeprof ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/bin/jeprof /usr/local/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/include/jemalloc/jemalloc.h ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/include/jemalloc
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/include/jemalloc/jemalloc.h /usr/local/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/lib/libjemalloc.so.2 ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/lib
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.so.2 /usr/local/lib
|
||||||
|
ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
|
||||||
|
/usr/bin/install -c -d /usr/local/lib
|
||||||
|
if [ -f ${binary_dir}/build/lib/libjemalloc.a ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/lib/libjemalloc_pic.a ]; then
|
||||||
|
/usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc_pic.a /usr/local/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/lib/pkgconfig
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/lib/pkgconfig/jemalloc.pc /usr/local/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/share/doc/jemalloc
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/share/doc/jemalloc/jemalloc.html /usr/local/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${binary_dir}/build/share/man/man3/jemalloc.3 ]; then
|
||||||
|
/usr/bin/install -c -d /usr/local/share/man/man3
|
||||||
|
/usr/bin/install -c -m 644 ${binary_dir}/build/share/man/man3/jemalloc.3 /usr/local/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function install_lib() {
|
function install_lib() {
|
||||||
# Remove links
|
# Remove links
|
||||||
|
@ -199,6 +242,8 @@ function install_lib() {
|
||||||
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
${csudo} ln -sf ${lib_link_dir}/libtaos.1.dylib ${lib_link_dir}/libtaos.dylib
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
install_jemalloc
|
||||||
|
|
||||||
if [ "$osType" != "Darwin" ]; then
|
if [ "$osType" != "Darwin" ]; then
|
||||||
${csudo} ldconfig
|
${csudo} ldconfig
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -30,7 +30,7 @@ else
|
||||||
install_dir="${release_dir}/TDengine-server-${version}"
|
install_dir="${release_dir}/TDengine-server-${version}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Directories and files.
|
# Directories and files
|
||||||
if [ "$pagMode" == "lite" ]; then
|
if [ "$pagMode" == "lite" ]; then
|
||||||
strip ${build_dir}/bin/taosd
|
strip ${build_dir}/bin/taosd
|
||||||
strip ${build_dir}/bin/taos
|
strip ${build_dir}/bin/taos
|
||||||
|
@ -73,6 +73,39 @@ mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/taos
|
||||||
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_deb} ${install_dir}/init.d/tarbitratord.deb || :
|
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_deb} ${install_dir}/init.d/tarbitratord.deb || :
|
||||||
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_rpm} ${install_dir}/init.d/tarbitratord.rpm || :
|
mkdir -p ${install_dir}/init.d && cp ${init_file_tarbitrator_rpm} ${install_dir}/init.d/tarbitratord.rpm || :
|
||||||
|
|
||||||
|
if [ -f ${build_dir}/bin/jemalloc-config ]; then
|
||||||
|
mkdir -p ${install_dir}/jemalloc/{bin,lib,lib/pkgconfig,include/jemalloc,share/doc/jemalloc,share/man/man3}
|
||||||
|
cp ${build_dir}/bin/jemalloc-config ${install_dir}/jemalloc/bin
|
||||||
|
if [ -f ${build_dir}/bin/jemalloc.sh ]; then
|
||||||
|
cp ${build_dir}/bin/jemalloc.sh ${install_dir}/jemalloc/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/bin/jeprof ]; then
|
||||||
|
cp ${build_dir}/bin/jeprof ${install_dir}/jemalloc/bin
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/include/jemalloc/jemalloc.h ]; then
|
||||||
|
cp ${build_dir}/include/jemalloc/jemalloc.h ${install_dir}/jemalloc/include/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc.so.2 ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc.so.2 ${install_dir}/jemalloc/lib
|
||||||
|
ln -sf libjemalloc.so.2 ${install_dir}/jemalloc/lib/libjemalloc.so
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc.a ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc.a ${install_dir}/jemalloc/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/libjemalloc_pic.a ]; then
|
||||||
|
cp ${build_dir}/lib/libjemalloc_pic.a ${install_dir}/jemalloc/lib
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/lib/pkgconfig/jemalloc.pc ]; then
|
||||||
|
cp ${build_dir}/lib/pkgconfig/jemalloc.pc ${install_dir}/jemalloc/lib/pkgconfig
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/share/doc/jemalloc/jemalloc.html ]; then
|
||||||
|
cp ${build_dir}/share/doc/jemalloc/jemalloc.html ${install_dir}/jemalloc/share/doc/jemalloc
|
||||||
|
fi
|
||||||
|
if [ -f ${build_dir}/share/man/man3/jemalloc.3 ]; then
|
||||||
|
cp ${build_dir}/share/man/man3/jemalloc.3 ${install_dir}/jemalloc/share/man/man3
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$verMode" == "cluster" ]; then
|
if [ "$verMode" == "cluster" ]; then
|
||||||
sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >> remove_temp.sh
|
sed 's/verMode=edge/verMode=cluster/g' ${install_dir}/bin/remove.sh >> remove_temp.sh
|
||||||
mv remove_temp.sh ${install_dir}/bin/remove.sh
|
mv remove_temp.sh ${install_dir}/bin/remove.sh
|
||||||
|
|
|
@ -123,6 +123,8 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
|
||||||
*/
|
*/
|
||||||
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
|
||||||
|
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo);
|
||||||
|
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
|
||||||
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);
|
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);
|
||||||
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
bool tscGroupbyColumn(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsTopBotQuery(SQueryInfo* pQueryInfo);
|
bool tscIsTopBotQuery(SQueryInfo* pQueryInfo);
|
||||||
|
|
|
@ -283,6 +283,7 @@ typedef struct SSqlStream {
|
||||||
int64_t ctime; // stream created time
|
int64_t ctime; // stream created time
|
||||||
int64_t stime; // stream next executed time
|
int64_t stime; // stream next executed time
|
||||||
int64_t etime; // stream end query time, when time is larger then etime, the stream will be closed
|
int64_t etime; // stream end query time, when time is larger then etime, the stream will be closed
|
||||||
|
int64_t ltime; // stream last row time in stream table
|
||||||
SInterval interval;
|
SInterval interval;
|
||||||
void * pTimer;
|
void * pTimer;
|
||||||
|
|
||||||
|
|
|
@ -774,6 +774,10 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
||||||
index = 0;
|
index = 0;
|
||||||
sToken = tStrGetToken(sql, &index, false);
|
sToken = tStrGetToken(sql, &index, false);
|
||||||
|
|
||||||
|
if (sToken.type == TK_ILLEGAL) {
|
||||||
|
return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z);
|
||||||
|
}
|
||||||
|
|
||||||
if (sToken.type == TK_RP) {
|
if (sToken.type == TK_RP) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ typedef struct SMultiTbStmt {
|
||||||
bool nameSet;
|
bool nameSet;
|
||||||
bool tagSet;
|
bool tagSet;
|
||||||
uint64_t currentUid;
|
uint64_t currentUid;
|
||||||
|
char *sqlstr;
|
||||||
uint32_t tbNum;
|
uint32_t tbNum;
|
||||||
SStrToken tbname;
|
SStrToken tbname;
|
||||||
SStrToken stbname;
|
SStrToken stbname;
|
||||||
|
@ -1203,7 +1204,6 @@ static int insertBatchStmtExecute(STscStmt* pStmt) {
|
||||||
return pStmt->pSql->res.code;
|
return pStmt->pSql->res.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
int32_t ret = TSDB_CODE_SUCCESS;
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
@ -1233,28 +1233,28 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
||||||
pStmt->mtb.tagSet = true;
|
pStmt->mtb.tagSet = true;
|
||||||
|
|
||||||
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
if (sToken.n > 0 && sToken.type == TK_VALUES) {
|
if (sToken.n > 0 && (sToken.type == TK_VALUES || sToken.type == TK_LP)) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sToken.n <= 0 || sToken.type != TK_USING) {
|
if (sToken.n <= 0 || sToken.type != TK_USING) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return tscSQLSyntaxErrMsg(pCmd->payload, "keywords USING is expected", sToken.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) {
|
if (sToken.n <= 0 || ((sToken.type != TK_ID) && (sToken.type != TK_STRING))) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z);
|
||||||
}
|
}
|
||||||
pStmt->mtb.stbname = sToken;
|
pStmt->mtb.stbname = sToken;
|
||||||
|
|
||||||
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
if (sToken.n <= 0 || sToken.type != TK_TAGS) {
|
if (sToken.n <= 0 || sToken.type != TK_TAGS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
if (sToken.n <= 0 || sToken.type != TK_LP) {
|
if (sToken.n <= 0 || sToken.type != TK_LP) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken));
|
pStmt->mtb.tags = taosArrayInit(4, sizeof(SStrToken));
|
||||||
|
@ -1286,19 +1286,17 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
|
||||||
if (sToken.n <= 0 || sToken.type != TK_VALUES) {
|
if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
pStmt->mtb.values = sToken;
|
pStmt->mtb.values = sToken;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAOS_BIND* tags) {
|
int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAOS_BIND* tags) {
|
||||||
size_t tagNum = taosArrayGetSize(pStmt->mtb.tags);
|
size_t tagNum = taosArrayGetSize(pStmt->mtb.tags);
|
||||||
size_t size = 1048576;
|
size_t size = 1048576;
|
||||||
|
@ -1373,14 +1371,17 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pSql->sqlstr);
|
if (pStmt->mtb.sqlstr == NULL) {
|
||||||
|
pStmt->mtb.sqlstr = pSql->sqlstr;
|
||||||
|
} else {
|
||||||
|
tfree(pSql->sqlstr);
|
||||||
|
}
|
||||||
|
|
||||||
pSql->sqlstr = str;
|
pSql->sqlstr = str;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// interface functions
|
// interface functions
|
||||||
|
|
||||||
|
@ -1561,7 +1562,6 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
|
||||||
}
|
}
|
||||||
|
|
||||||
pStmt->mtb.nameSet = true;
|
pStmt->mtb.nameSet = true;
|
||||||
pStmt->mtb.tagSet = true;
|
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
tscDebug("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||||
|
|
||||||
|
@ -1634,6 +1634,7 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
||||||
taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList);
|
taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList);
|
||||||
pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL;
|
pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL;
|
||||||
taosArrayDestroy(pStmt->mtb.tags);
|
taosArrayDestroy(pStmt->mtb.tags);
|
||||||
|
tfree(pStmt->mtb.sqlstr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ static int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCm
|
||||||
static int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
|
static int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
|
||||||
static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken);
|
static int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* offsetToken);
|
||||||
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding);
|
static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSliding);
|
||||||
|
static int32_t validateStateWindowNode(SSqlCmd* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable);
|
||||||
|
|
||||||
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem);
|
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExprItem* pItem);
|
||||||
|
|
||||||
|
@ -395,11 +396,18 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
const char* msg2 = "name too long";
|
const char* msg2 = "name too long";
|
||||||
|
|
||||||
SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt);
|
SCreateDbInfo* pCreateDB = &(pInfo->pMiscInfo->dbOpt);
|
||||||
if (tscValidateName(&pCreateDB->dbname) != TSDB_CODE_SUCCESS) {
|
if (pCreateDB->dbname.n >= TSDB_DB_NAME_LEN) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[TSDB_DB_NAME_LEN] = {0};
|
||||||
|
SStrToken token = taosTokenDup(&pCreateDB->dbname, buf, tListLen(buf));
|
||||||
|
|
||||||
|
if (tscValidateName(&token) != TSDB_CODE_SUCCESS) {
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &(pCreateDB->dbname));
|
int32_t ret = tNameSetDbName(&pTableMetaInfo->name, getAccountId(pSql), &token);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
@ -851,6 +859,59 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS
|
||||||
// The following part is used to check for the invalid query expression.
|
// The following part is used to check for the invalid query expression.
|
||||||
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
|
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
|
||||||
}
|
}
|
||||||
|
static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable) {
|
||||||
|
|
||||||
|
const char* msg1 = "invalid column name";
|
||||||
|
const char* msg3 = "not support state_window with group by ";
|
||||||
|
const char* msg4 = "function not support for super table query";
|
||||||
|
|
||||||
|
SStrToken *col = &(pSqlNode->windowstateVal.col) ;
|
||||||
|
if (col->z == NULL || col->n <= 0) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->colList == NULL) {
|
||||||
|
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||||
|
}
|
||||||
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
pQueryInfo->groupbyExpr.numOfGroupCols = 1;
|
||||||
|
|
||||||
|
//TODO(dengyihao): check tag column
|
||||||
|
if (isStable) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
|
if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
|
||||||
|
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
|
||||||
|
if (pGroupExpr->columnInfo == NULL) {
|
||||||
|
pGroupExpr->columnInfo = taosArrayInit(4, sizeof(SColIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
|
||||||
|
if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema);
|
||||||
|
SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
|
||||||
|
taosArrayPush(pGroupExpr->columnInfo, &colIndex);
|
||||||
|
pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
|
||||||
|
pQueryInfo->stateWindow = true;
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) {
|
int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pSqlNode) {
|
||||||
const char* msg1 = "gap should be fixed time window";
|
const char* msg1 = "gap should be fixed time window";
|
||||||
|
@ -885,11 +946,17 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS
|
||||||
if (pQueryInfo->sessionWindow.gap != 0 && pQueryInfo->interval.interval != 0) {
|
if (pQueryInfo->sessionWindow.gap != 0 && pQueryInfo->interval.interval != 0) {
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
if (pQueryInfo->sessionWindow.gap == 0) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
if (getColumnIndexByName(pCmd, col, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
}
|
}
|
||||||
|
if (index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||||
|
|
||||||
|
@ -2896,6 +2963,9 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (tscIsSessionWindowQuery(pQueryInfo)) {
|
||||||
|
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -6239,7 +6309,7 @@ static int32_t doTagFunctionCheck(SQueryInfo* pQueryInfo) {
|
||||||
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||||
const char* msg1 = "functions/columns not allowed in group by query";
|
const char* msg1 = "functions/columns not allowed in group by query";
|
||||||
const char* msg2 = "projection query on columns not allowed";
|
const char* msg2 = "projection query on columns not allowed";
|
||||||
const char* msg3 = "group by not allowed on projection query";
|
const char* msg3 = "group by/session/state_window not allowed on projection query";
|
||||||
const char* msg4 = "retrieve tags not compatible with group by or interval query";
|
const char* msg4 = "retrieve tags not compatible with group by or interval query";
|
||||||
const char* msg5 = "functions can not be mixed up";
|
const char* msg5 = "functions can not be mixed up";
|
||||||
|
|
||||||
|
@ -6255,6 +6325,9 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tscIsProjectionQuery(pQueryInfo) && tscIsSessionWindowQuery(pQueryInfo)) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
}
|
||||||
|
|
||||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0) {
|
||||||
// check if all the tags prj columns belongs to the group by columns
|
// check if all the tags prj columns belongs to the group by columns
|
||||||
|
@ -6824,6 +6897,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
if (isTimeWindowQuery(pQueryInfo) && (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
||||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
|
||||||
}
|
}
|
||||||
|
@ -7498,6 +7572,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
const char* msg1 = "point interpolation query needs timestamp";
|
const char* msg1 = "point interpolation query needs timestamp";
|
||||||
const char* msg2 = "too many tables in from clause";
|
const char* msg2 = "too many tables in from clause";
|
||||||
const char* msg3 = "start(end) time of query range required or time range too large";
|
const char* msg3 = "start(end) time of query range required or time range too large";
|
||||||
|
const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column";
|
||||||
const char* msg9 = "only tag query not compatible with normal column filter";
|
const char* msg9 = "only tag query not compatible with normal column filter";
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
|
@ -7556,11 +7631,25 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) {
|
if (validateIntervalNode(pSql, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
} else {
|
} else {
|
||||||
if (isTimeWindowQuery(pQueryInfo) &&
|
if (isTimeWindowQuery(pQueryInfo)) {
|
||||||
(validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS)) {
|
// check if the first column of the nest query result is timestamp column
|
||||||
|
SColumn* pCol = taosArrayGetP(pQueryInfo->colList, 0);
|
||||||
|
if (pCol->info.type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
|
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validateFunctionsInIntervalOrGroupbyQuery(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set order by info
|
||||||
|
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||||
|
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMeta)) !=
|
||||||
|
TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pQueryInfo->command = TSDB_SQL_SELECT;
|
pQueryInfo->command = TSDB_SQL_SELECT;
|
||||||
|
|
||||||
|
@ -7612,7 +7701,10 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
// parse the window_state
|
||||||
|
if (validateStateWindowNode(pCmd, pQueryInfo, pSqlNode, isSTable) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
// set order by info
|
// set order by info
|
||||||
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) !=
|
if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMetaInfo->pTableMeta)) !=
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
|
@ -7653,6 +7745,10 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
* transfer sql functions that need secondary merge into another format
|
* transfer sql functions that need secondary merge into another format
|
||||||
* in dealing with super table queries such as: count/first/last
|
* in dealing with super table queries such as: count/first/last
|
||||||
*/
|
*/
|
||||||
|
if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSTable) {
|
if (isSTable) {
|
||||||
tscTansformFuncForSTableQuery(pQueryInfo);
|
tscTansformFuncForSTableQuery(pQueryInfo);
|
||||||
if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
|
if (hasUnsupportFunctionsForSTableQuery(pCmd, pQueryInfo)) {
|
||||||
|
@ -7660,10 +7756,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (validateSessionNode(pCmd, pQueryInfo, pSqlNode) != TSDB_CODE_SUCCESS) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no result due to invalid query time range
|
// no result due to invalid query time range
|
||||||
if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
|
if (pQueryInfo->window.skey > pQueryInfo->window.ekey) {
|
||||||
pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
||||||
|
@ -7710,8 +7802,8 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
||||||
|
|
||||||
SExprInfo** p = NULL;
|
SExprInfo** p = NULL;
|
||||||
int32_t numOfExpr = 0;
|
int32_t numOfExpr = 0;
|
||||||
|
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr);
|
code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr);
|
||||||
|
|
||||||
if (pQueryInfo->exprList1 == NULL) {
|
if (pQueryInfo->exprList1 == NULL) {
|
||||||
pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES);
|
pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES);
|
||||||
}
|
}
|
||||||
|
|
|
@ -477,7 +477,6 @@ int doBuildAndSendMsg(SSqlObj *pSql) {
|
||||||
pCmd->command == TSDB_SQL_INSERT ||
|
pCmd->command == TSDB_SQL_INSERT ||
|
||||||
pCmd->command == TSDB_SQL_CONNECT ||
|
pCmd->command == TSDB_SQL_CONNECT ||
|
||||||
pCmd->command == TSDB_SQL_HB ||
|
pCmd->command == TSDB_SQL_HB ||
|
||||||
// pCmd->command == TSDB_SQL_META ||
|
|
||||||
pCmd->command == TSDB_SQL_STABLEVGROUP) {
|
pCmd->command == TSDB_SQL_STABLEVGROUP) {
|
||||||
pRes->code = tscBuildMsg[pCmd->command](pSql, NULL);
|
pRes->code = tscBuildMsg[pCmd->command](pSql, NULL);
|
||||||
}
|
}
|
||||||
|
@ -857,6 +856,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->simpleAgg = query.simpleAgg;
|
pQueryMsg->simpleAgg = query.simpleAgg;
|
||||||
pQueryMsg->pointInterpQuery = query.pointInterpQuery;
|
pQueryMsg->pointInterpQuery = query.pointInterpQuery;
|
||||||
pQueryMsg->needReverseScan = query.needReverseScan;
|
pQueryMsg->needReverseScan = query.needReverseScan;
|
||||||
|
pQueryMsg->stateWindow = query.stateWindow;
|
||||||
|
|
||||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||||
pQueryMsg->sqlstrLen = htonl(sqlLen);
|
pQueryMsg->sqlstrLen = htonl(sqlLen);
|
||||||
|
@ -2469,7 +2469,7 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
||||||
pNew->fp = fp;
|
pNew->fp = fp;
|
||||||
pNew->param = (void *)pSql->self;
|
pNew->param = (void *)pSql->self;
|
||||||
|
|
||||||
tscDebug("0x%"PRIx64" metaRid from %" PRId64 " to %" PRId64 , pSql->self, pSql->metaRid, pNew->self);
|
tscDebug("0x%"PRIx64" metaRid from 0x%" PRIx64 " to 0x%" PRIx64 , pSql->self, pSql->metaRid, pNew->self);
|
||||||
|
|
||||||
pSql->metaRid = pNew->self;
|
pSql->metaRid = pNew->self;
|
||||||
int32_t code = tscBuildAndSendRequest(pNew, NULL);
|
int32_t code = tscBuildAndSendRequest(pNew, NULL);
|
||||||
|
|
|
@ -627,7 +627,7 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) {
|
||||||
|
|
||||||
char *z = NULL;
|
char *z = NULL;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
z = strstr(pCmd->payload, "invalid SQL");
|
z = strstr(pCmd->payload, "invalid operation");
|
||||||
if (z == NULL) {
|
if (z == NULL) {
|
||||||
z = strstr(pCmd->payload, "syntax error");
|
z = strstr(pCmd->payload, "syntax error");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
#include "tscProfile.h"
|
#include "tscProfile.h"
|
||||||
|
#include "tscSubquery.h"
|
||||||
|
|
||||||
static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOfRows);
|
static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOfRows);
|
static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOfRows);
|
||||||
|
@ -47,8 +48,8 @@ static bool isProjectStream(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
static int64_t tscGetRetryDelayTime(SSqlStream* pStream, int64_t slidingTime, int16_t prec) {
|
static int64_t tscGetRetryDelayTime(SSqlStream* pStream, int64_t slidingTime, int16_t prec) {
|
||||||
float retryRangeFactor = 0.3f;
|
float retryRangeFactor = 0.3f;
|
||||||
int64_t retryDelta = (int64_t)(tsStreamCompRetryDelay * retryRangeFactor);
|
int64_t retryDelta = (int64_t)(tsRetryStreamCompDelay * retryRangeFactor);
|
||||||
retryDelta = ((rand() % retryDelta) + tsStreamCompRetryDelay) * 1000L;
|
retryDelta = ((rand() % retryDelta) + tsRetryStreamCompDelay) * 1000L;
|
||||||
|
|
||||||
if (pStream->interval.intervalUnit != 'n' && pStream->interval.intervalUnit != 'y') {
|
if (pStream->interval.intervalUnit != 'n' && pStream->interval.intervalUnit != 'y') {
|
||||||
// change to ms
|
// change to ms
|
||||||
|
@ -575,6 +576,14 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
|
||||||
|
|
||||||
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
pStream->stime = tscGetStreamStartTimestamp(pSql, pStream, pStream->stime);
|
||||||
|
|
||||||
|
// set stime with ltime if ltime > stime
|
||||||
|
const char* dstTable = pStream->dstTable? pStream->dstTable: "";
|
||||||
|
tscDebug(" CQ table=%s ltime is %"PRId64, dstTable, pStream->ltime);
|
||||||
|
if(pStream->ltime != INT64_MIN && pStream->ltime > pStream->stime) {
|
||||||
|
tscWarn(" CQ set stream %s stime=%"PRId64" replace with ltime=%"PRId64" if ltime>0 ", dstTable, pStream->stime, pStream->ltime);
|
||||||
|
pStream->stime = pStream->ltime;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
||||||
pCmd->command = TSDB_SQL_SELECT;
|
pCmd->command = TSDB_SQL_SELECT;
|
||||||
|
|
||||||
|
@ -590,7 +599,66 @@ void tscSetStreamDestTable(SSqlStream* pStream, const char* dstTable) {
|
||||||
pStream->dstTable = dstTable;
|
pStream->dstTable = dstTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
// fetchFp call back
|
||||||
|
void fetchFpStreamLastRow(void* param ,TAOS_RES* res, int num) {
|
||||||
|
SSqlStream* pStream = (SSqlStream*)param;
|
||||||
|
SSqlObj* pSql = res;
|
||||||
|
|
||||||
|
// get row data set to ltime
|
||||||
|
tscSetSqlOwner(pSql);
|
||||||
|
TAOS_ROW row = doSetResultRowData(pSql);
|
||||||
|
if( row && row[0] ) {
|
||||||
|
pStream->ltime = *((int64_t*)row[0]);
|
||||||
|
const char* dstTable = pStream->dstTable? pStream->dstTable: "";
|
||||||
|
tscDebug(" CQ stream table=%s last row time=%"PRId64" .", dstTable, pStream->ltime);
|
||||||
|
}
|
||||||
|
tscClearSqlOwner(pSql);
|
||||||
|
|
||||||
|
// no condition call
|
||||||
|
tscCreateStream(param, pStream->pSql, TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fp callback
|
||||||
|
void fpStreamLastRow(void* param ,TAOS_RES* res, int code) {
|
||||||
|
// check result successful
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscCreateStream(param, res, TSDB_CODE_SUCCESS);
|
||||||
|
taos_free_result(res);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// asynchronous fetch last row data
|
||||||
|
taos_fetch_rows_a(res, fetchFpStreamLastRow, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbParseSql(void* param, TAOS_RES* res, int code) {
|
||||||
|
// check result successful
|
||||||
|
SSqlStream* pStream = (SSqlStream*)param;
|
||||||
|
SSqlObj* pSql = pStream->pSql;
|
||||||
|
SSqlCmd* pCmd = &pSql->cmd;
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
pSql->res.code = code;
|
||||||
|
tscDebug("0x%"PRIx64" open stream parse sql failed, sql:%s, reason:%s, code:%s", pSql->self, pSql->sqlstr, pCmd->payload, tstrerror(code));
|
||||||
|
pStream->fp(pStream->param, NULL, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check dstTable valid
|
||||||
|
if(pStream->dstTable == NULL || strlen(pStream->dstTable) == 0) {
|
||||||
|
tscDebug(" cbParseSql dstTable is empty.");
|
||||||
|
tscCreateStream(param, res, code);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// query stream last row time async
|
||||||
|
char sql[128] = "";
|
||||||
|
sprintf(sql, "select last_row(*) from %s;", pStream->dstTable);
|
||||||
|
taos_query_a(pSql->pTscObj, sql, fpStreamLastRow, param);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* dstTable, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||||
int64_t stime, void *param, void (*callback)(void *)) {
|
int64_t stime, void *param, void (*callback)(void *)) {
|
||||||
STscObj *pObj = (STscObj *)taos;
|
STscObj *pObj = (STscObj *)taos;
|
||||||
if (pObj == NULL || pObj->signature != pObj) return NULL;
|
if (pObj == NULL || pObj->signature != pObj) return NULL;
|
||||||
|
@ -613,11 +681,16 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pStream->ltime = INT64_MIN;
|
||||||
pStream->stime = stime;
|
pStream->stime = stime;
|
||||||
pStream->fp = fp;
|
pStream->fp = fp;
|
||||||
pStream->callback = callback;
|
pStream->callback = callback;
|
||||||
pStream->param = param;
|
pStream->param = param;
|
||||||
pStream->pSql = pSql;
|
pStream->pSql = pSql;
|
||||||
|
pSql->pStream = pStream;
|
||||||
|
pSql->param = pStream;
|
||||||
|
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||||
|
tscSetStreamDestTable(pStream, dstTable);
|
||||||
|
|
||||||
pSql->pStream = pStream;
|
pSql->pStream = pStream;
|
||||||
pSql->param = pStream;
|
pSql->param = pStream;
|
||||||
|
@ -640,10 +713,17 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
|
|
||||||
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
tscDebugL("0x%"PRIx64" SQL: %s", pSql->self, pSql->sqlstr);
|
||||||
|
|
||||||
|
pSql->fp = cbParseSql;
|
||||||
|
pSql->fetchFp = cbParseSql;
|
||||||
|
|
||||||
|
registerSqlObj(pSql);
|
||||||
|
|
||||||
int32_t code = tsParseSql(pSql, true);
|
int32_t code = tsParseSql(pSql, true);
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
tscCreateStream(pStream, pSql, code);
|
cbParseSql(pStream, pSql, code);
|
||||||
} else if (code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
} else if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||||
|
tscDebug(" CQ taso_open_stream IN Process. sql=%s", sqlstr);
|
||||||
|
} else {
|
||||||
tscError("0x%"PRIx64" open stream failed, sql:%s, code:%s", pSql->self, sqlstr, tstrerror(code));
|
tscError("0x%"PRIx64" open stream failed, sql:%s, code:%s", pSql->self, sqlstr, tstrerror(code));
|
||||||
taosReleaseRef(tscObjRef, pSql->self);
|
taosReleaseRef(tscObjRef, pSql->self);
|
||||||
free(pStream);
|
free(pStream);
|
||||||
|
@ -653,6 +733,11 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
return pStream;
|
return pStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||||
|
int64_t stime, void *param, void (*callback)(void *)) {
|
||||||
|
return taos_open_stream_withname(taos, "", sqlstr, fp, stime, param, callback);
|
||||||
|
}
|
||||||
|
|
||||||
void taos_close_stream(TAOS_STREAM *handle) {
|
void taos_close_stream(TAOS_STREAM *handle) {
|
||||||
SSqlStream *pStream = (SSqlStream *)handle;
|
SSqlStream *pStream = (SSqlStream *)handle;
|
||||||
|
|
||||||
|
|
|
@ -1469,6 +1469,8 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
|
||||||
|
|
||||||
SSqlRes* pRes1 = &pParentSql->pSubs[i]->res;
|
SSqlRes* pRes1 = &pParentSql->pSubs[i]->res;
|
||||||
|
|
||||||
|
pParentSql->res.precision = pRes1->precision;
|
||||||
|
|
||||||
if (pRes1->row > 0 && pRes1->numOfRows > 0) {
|
if (pRes1->row > 0 && pRes1->numOfRows > 0) {
|
||||||
tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self,
|
tscDebug("0x%"PRIx64" sub:0x%"PRIx64" index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql->self,
|
||||||
pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal);
|
pParentSql->pSubs[i]->self, i, pRes1->numOfRows, pRes1->numOfTotal);
|
||||||
|
|
|
@ -434,6 +434,9 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) {
|
||||||
|
return pQueryInfo->sessionWindow.gap > 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool tscNeedReverseScan(SQueryInfo* pQueryInfo) {
|
bool tscNeedReverseScan(SQueryInfo* pQueryInfo) {
|
||||||
size_t numOfExprs = tscNumOfExprs(pQueryInfo);
|
size_t numOfExprs = tscNumOfExprs(pQueryInfo);
|
||||||
|
@ -777,7 +780,9 @@ SSDataBlock* doGetDataBlock(void* param, bool* newgroup) {
|
||||||
SSqlRes* pRes = &pSql->res;
|
SSqlRes* pRes = &pSql->res;
|
||||||
|
|
||||||
SSDataBlock* pBlock = pInput->block;
|
SSDataBlock* pBlock = pInput->block;
|
||||||
|
if (pOperator->pRuntimeEnv != NULL) {
|
||||||
pOperator->pRuntimeEnv->current = pInput->pTableQueryInfo;
|
pOperator->pRuntimeEnv->current = pInput->pTableQueryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
pBlock->info.rows = pRes->numOfRows;
|
pBlock->info.rows = pRes->numOfRows;
|
||||||
if (pRes->numOfRows != 0) {
|
if (pRes->numOfRows != 0) {
|
||||||
|
@ -801,6 +806,24 @@ SSDataBlock* doGetDataBlock(void* param, bool* newgroup) {
|
||||||
return pBlock;
|
return pBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fetchNextBlockIfCompleted(SOperatorInfo* pOperator, bool* newgroup) {
|
||||||
|
SJoinOperatorInfo* pJoinInfo = pOperator->info;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < pOperator->numOfUpstream; ++i) {
|
||||||
|
SJoinStatus* pStatus = &pJoinInfo->status[i];
|
||||||
|
if (pStatus->pBlock == NULL || pStatus->index >= pStatus->pBlock->info.rows) {
|
||||||
|
pStatus->pBlock = pOperator->upstream[i]->exec(pOperator->upstream[i], newgroup);
|
||||||
|
pStatus->index = 0;
|
||||||
|
|
||||||
|
if (pStatus->pBlock == NULL) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
pJoinInfo->resultInfo.total += pJoinInfo->pRes->info.rows;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SSDataBlock* doDataBlockJoin(void* param, bool* newgroup) {
|
SSDataBlock* doDataBlockJoin(void* param, bool* newgroup) {
|
||||||
SOperatorInfo *pOperator = (SOperatorInfo*) param;
|
SOperatorInfo *pOperator = (SOperatorInfo*) param;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
@ -813,20 +836,10 @@ SSDataBlock* doDataBlockJoin(void* param, bool* newgroup) {
|
||||||
pJoinInfo->pRes->info.rows = 0;
|
pJoinInfo->pRes->info.rows = 0;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
for (int32_t i = 0; i < pOperator->numOfUpstream; ++i) {
|
fetchNextBlockIfCompleted(pOperator, newgroup);
|
||||||
SJoinStatus* pStatus = &pJoinInfo->status[i];
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
if (pStatus->pBlock == NULL || pStatus->index >= pStatus->pBlock->info.rows) {
|
|
||||||
pStatus->pBlock = pOperator->upstream[i]->exec(pOperator->upstream[i], newgroup);
|
|
||||||
pStatus->index = 0;
|
|
||||||
|
|
||||||
if (pStatus->pBlock == NULL) {
|
|
||||||
pOperator->status = OP_EXEC_DONE;
|
|
||||||
|
|
||||||
pJoinInfo->resultInfo.total += pJoinInfo->pRes->info.rows;
|
|
||||||
return pJoinInfo->pRes;
|
return pJoinInfo->pRes;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SJoinStatus* st0 = &pJoinInfo->status[0];
|
SJoinStatus* st0 = &pJoinInfo->status[0];
|
||||||
SColumnInfoData* p0 = taosArrayGet(st0->pBlock->pDataBlock, 0);
|
SColumnInfoData* p0 = taosArrayGet(st0->pBlock->pDataBlock, 0);
|
||||||
|
@ -844,8 +857,12 @@ SSDataBlock* doDataBlockJoin(void* param, bool* newgroup) {
|
||||||
|
|
||||||
if (ts[st->index] < ts0[st0->index]) { // less than the first
|
if (ts[st->index] < ts0[st0->index]) { // less than the first
|
||||||
prefixEqual = false;
|
prefixEqual = false;
|
||||||
|
|
||||||
if ((++(st->index)) >= st->pBlock->info.rows) {
|
if ((++(st->index)) >= st->pBlock->info.rows) {
|
||||||
break;
|
fetchNextBlockIfCompleted(pOperator, newgroup);
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return pJoinInfo->pRes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (ts[st->index] > ts0[st0->index]) { // greater than the first;
|
} else if (ts[st->index] > ts0[st0->index]) { // greater than the first;
|
||||||
if (prefixEqual == true) {
|
if (prefixEqual == true) {
|
||||||
|
@ -853,12 +870,19 @@ SSDataBlock* doDataBlockJoin(void* param, bool* newgroup) {
|
||||||
for (int32_t j = 0; j < i; ++j) {
|
for (int32_t j = 0; j < i; ++j) {
|
||||||
SJoinStatus* stx = &pJoinInfo->status[j];
|
SJoinStatus* stx = &pJoinInfo->status[j];
|
||||||
if ((++(stx->index)) >= stx->pBlock->info.rows) {
|
if ((++(stx->index)) >= stx->pBlock->info.rows) {
|
||||||
break;
|
|
||||||
|
fetchNextBlockIfCompleted(pOperator, newgroup);
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return pJoinInfo->pRes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((++(st0->index)) >= st0->pBlock->info.rows) {
|
if ((++(st0->index)) >= st0->pBlock->info.rows) {
|
||||||
break;
|
fetchNextBlockIfCompleted(pOperator, newgroup);
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return pJoinInfo->pRes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1129,6 +1153,19 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
|
||||||
memcpy(schema, pSchema, numOfCol1*sizeof(SSchema));
|
memcpy(schema, pSchema, numOfCol1*sizeof(SSchema));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update the exprinfo
|
||||||
|
int32_t numOfOutput = (int32_t)tscNumOfExprs(px);
|
||||||
|
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||||
|
SExprInfo* pex = taosArrayGetP(px->exprList, i);
|
||||||
|
int32_t colId = pex->base.colInfo.colId;
|
||||||
|
for(int32_t j = 0; j < pSourceOperator->numOfOutput; ++j) {
|
||||||
|
if (colId == schema[j].colId) {
|
||||||
|
pex->base.colInfo.colIndex = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
px->pQInfo = createQInfoFromQueryNode(px, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN);
|
px->pQInfo = createQInfoFromQueryNode(px, &tableGroupInfo, pSourceOperator, NULL, NULL, MASTER_SCAN);
|
||||||
tfree(pColumnInfo);
|
tfree(pColumnInfo);
|
||||||
tfree(schema);
|
tfree(schema);
|
||||||
|
@ -4202,11 +4239,13 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
|
||||||
pQueryAttr->simpleAgg = isSimpleAggregate(pQueryInfo);
|
pQueryAttr->simpleAgg = isSimpleAggregate(pQueryInfo);
|
||||||
pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo);
|
pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo);
|
||||||
pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type);
|
pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type);
|
||||||
pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo);
|
pQueryAttr->groupbyColumn = (!pQueryInfo->stateWindow) && tscGroupbyColumn(pQueryInfo);
|
||||||
pQueryAttr->queryBlockDist = isBlockDistQuery(pQueryInfo);
|
pQueryAttr->queryBlockDist = isBlockDistQuery(pQueryInfo);
|
||||||
pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo);
|
pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo);
|
||||||
pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo);
|
pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo);
|
||||||
pQueryAttr->distinctTag = pQueryInfo->distinctTag;
|
pQueryAttr->distinctTag = pQueryInfo->distinctTag;
|
||||||
|
pQueryAttr->sw = pQueryInfo->sessionWindow;
|
||||||
|
pQueryAttr->stateWindow = pQueryInfo->stateWindow;
|
||||||
|
|
||||||
pQueryAttr->numOfCols = numOfCols;
|
pQueryAttr->numOfCols = numOfCols;
|
||||||
pQueryAttr->numOfOutput = numOfOutput;
|
pQueryAttr->numOfOutput = numOfOutput;
|
||||||
|
@ -4214,9 +4253,9 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
|
||||||
pQueryAttr->slimit = pQueryInfo->slimit;
|
pQueryAttr->slimit = pQueryInfo->slimit;
|
||||||
pQueryAttr->order = pQueryInfo->order;
|
pQueryAttr->order = pQueryInfo->order;
|
||||||
pQueryAttr->fillType = pQueryInfo->fillType;
|
pQueryAttr->fillType = pQueryInfo->fillType;
|
||||||
pQueryAttr->groupbyColumn = tscGroupbyColumn(pQueryInfo);
|
|
||||||
pQueryAttr->havingNum = pQueryInfo->havingFieldNum;
|
pQueryAttr->havingNum = pQueryInfo->havingFieldNum;
|
||||||
|
|
||||||
|
|
||||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor
|
if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor
|
||||||
pQueryAttr->window = pQueryInfo->window;
|
pQueryAttr->window = pQueryInfo->window;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -319,7 +319,7 @@ int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
||||||
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
||||||
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
||||||
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols);
|
void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols);
|
||||||
int tdMergeDataCols(SDataCols *target, SDataCols *src, int rowsToMerge);
|
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset);
|
||||||
|
|
||||||
// ----------------- K-V data row structure
|
// ----------------- K-V data row structure
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern int8_t tsEnableTelemetryReporting;
|
||||||
extern char tsEmail[];
|
extern char tsEmail[];
|
||||||
extern char tsArbitrator[];
|
extern char tsArbitrator[];
|
||||||
extern int8_t tsArbOnline;
|
extern int8_t tsArbOnline;
|
||||||
|
extern int64_t tsArbOnlineTimestamp;
|
||||||
extern int32_t tsDnodeId;
|
extern int32_t tsDnodeId;
|
||||||
|
|
||||||
// common
|
// common
|
||||||
|
@ -75,7 +76,7 @@ extern int32_t tsMinSlidingTime;
|
||||||
extern int32_t tsMinIntervalTime;
|
extern int32_t tsMinIntervalTime;
|
||||||
extern int32_t tsMaxStreamComputDelay;
|
extern int32_t tsMaxStreamComputDelay;
|
||||||
extern int32_t tsStreamCompStartDelay;
|
extern int32_t tsStreamCompStartDelay;
|
||||||
extern int32_t tsStreamCompRetryDelay;
|
extern int32_t tsRetryStreamCompDelay;
|
||||||
extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
|
extern float tsStreamComputDelayRatio; // the delayed computing ration of the whole time window
|
||||||
extern int32_t tsProjectExecInterval;
|
extern int32_t tsProjectExecInterval;
|
||||||
extern int64_t tsMaxRetentWindow;
|
extern int64_t tsMaxRetentWindow;
|
||||||
|
|
|
@ -441,30 +441,35 @@ void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols)
|
||||||
pCols->numOfRows++;
|
pCols->numOfRows++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge) {
|
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset) {
|
||||||
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
||||||
ASSERT(target->numOfCols == source->numOfCols);
|
ASSERT(target->numOfCols == source->numOfCols);
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
if (pOffset == NULL) {
|
||||||
|
pOffset = &offset;
|
||||||
|
}
|
||||||
|
|
||||||
SDataCols *pTarget = NULL;
|
SDataCols *pTarget = NULL;
|
||||||
|
|
||||||
if (dataColsKeyLast(target) < dataColsKeyFirst(source)) { // No overlap
|
if ((target->numOfRows == 0) || (dataColsKeyLast(target) < dataColsKeyFirst(source))) { // No overlap
|
||||||
ASSERT(target->numOfRows + rowsToMerge <= target->maxPoints);
|
ASSERT(target->numOfRows + rowsToMerge <= target->maxPoints);
|
||||||
for (int i = 0; i < rowsToMerge; i++) {
|
for (int i = 0; i < rowsToMerge; i++) {
|
||||||
for (int j = 0; j < source->numOfCols; j++) {
|
for (int j = 0; j < source->numOfCols; j++) {
|
||||||
if (source->cols[j].len > 0) {
|
if (source->cols[j].len > 0) {
|
||||||
dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i), target->numOfRows,
|
dataColAppendVal(target->cols + j, tdGetColDataOfRow(source->cols + j, i + (*pOffset)), target->numOfRows,
|
||||||
target->maxPoints);
|
target->maxPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target->numOfRows++;
|
target->numOfRows++;
|
||||||
}
|
}
|
||||||
|
(*pOffset) += rowsToMerge;
|
||||||
} else {
|
} else {
|
||||||
pTarget = tdDupDataCols(target, true);
|
pTarget = tdDupDataCols(target, true);
|
||||||
if (pTarget == NULL) goto _err;
|
if (pTarget == NULL) goto _err;
|
||||||
|
|
||||||
int iter1 = 0;
|
int iter1 = 0;
|
||||||
int iter2 = 0;
|
tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, pOffset, source->numOfRows,
|
||||||
tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, &iter2, source->numOfRows,
|
|
||||||
pTarget->numOfRows + rowsToMerge);
|
pTarget->numOfRows + rowsToMerge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,12 @@ int32_t tsNumOfMnodes = 3;
|
||||||
int8_t tsEnableVnodeBak = 1;
|
int8_t tsEnableVnodeBak = 1;
|
||||||
int8_t tsEnableTelemetryReporting = 1;
|
int8_t tsEnableTelemetryReporting = 1;
|
||||||
int8_t tsArbOnline = 0;
|
int8_t tsArbOnline = 0;
|
||||||
|
int64_t tsArbOnlineTimestamp = TSDB_ARB_DUMMY_TIME;
|
||||||
char tsEmail[TSDB_FQDN_LEN] = {0};
|
char tsEmail[TSDB_FQDN_LEN] = {0};
|
||||||
int32_t tsDnodeId = 0;
|
int32_t tsDnodeId = 0;
|
||||||
|
|
||||||
// common
|
// common
|
||||||
int32_t tsRpcTimer = 1000;
|
int32_t tsRpcTimer = 300;
|
||||||
int32_t tsRpcMaxTime = 600; // seconds;
|
int32_t tsRpcMaxTime = 600; // seconds;
|
||||||
int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default
|
int32_t tsRpcForceTcp = 0; //disable this, means query, show command use udp protocol as default
|
||||||
int32_t tsMaxShellConns = 50000;
|
int32_t tsMaxShellConns = 50000;
|
||||||
|
@ -93,7 +94,7 @@ int32_t tsMaxStreamComputDelay = 20000;
|
||||||
int32_t tsStreamCompStartDelay = 10000;
|
int32_t tsStreamCompStartDelay = 10000;
|
||||||
|
|
||||||
// the stream computing delay time after executing failed, change accordingly
|
// the stream computing delay time after executing failed, change accordingly
|
||||||
int32_t tsStreamCompRetryDelay = 10;
|
int32_t tsRetryStreamCompDelay = 10*1000;
|
||||||
|
|
||||||
// The delayed computing ration. 10% of the whole computing time window by default.
|
// The delayed computing ration. 10% of the whole computing time window by default.
|
||||||
float tsStreamComputDelayRatio = 0.1f;
|
float tsStreamComputDelayRatio = 0.1f;
|
||||||
|
@ -710,7 +711,7 @@ static void doInitGlobalConfig(void) {
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
||||||
cfg.option = "retryStreamCompDelay";
|
cfg.option = "retryStreamCompDelay";
|
||||||
cfg.ptr = &tsStreamCompRetryDelay;
|
cfg.ptr = &tsRetryStreamCompDelay;
|
||||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||||
cfg.minValue = 10;
|
cfg.minValue = 10;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 050667e5b4d0eafa5387e4283e713559b421203f
|
Subproject commit 7a26c432f8b4203e42344ff3290b9b9b01b983d5
|
|
@ -1 +1 @@
|
||||||
Subproject commit 32e2c97a4cf7bedaa99f5d6dd8cb036e7f4470df
|
Subproject commit 3530c6df097134a410bacec6b3cd013ef38a61aa
|
|
@ -16,13 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package com.taosdata.jdbc;
|
package com.taosdata.jdbc;
|
||||||
|
|
||||||
import com.taosdata.jdbc.utils.TaosInfo;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.SQLWarning;
|
import java.sql.SQLWarning;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.taosdata.jdbc.utils.TaosInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JNI connector
|
* JNI connector
|
||||||
*/
|
*/
|
||||||
|
@ -276,23 +276,14 @@ public class TSDBJNIConnector {
|
||||||
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes);
|
||||||
|
|
||||||
public long prepareStmt(String sql) throws SQLException {
|
public long prepareStmt(String sql) throws SQLException {
|
||||||
Long stmt = 0L;
|
Long stmt = prepareStmtImp(sql.getBytes(), this.taos);
|
||||||
try {
|
if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) {
|
||||||
stmt = prepareStmtImp(sql.getBytes(), this.taos);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL);
|
||||||
} catch (Exception e) {
|
} else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
|
||||||
e.printStackTrace();
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stmt == TSDBConstants.JNI_CONNECTION_NULL) {
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||||
}
|
} else if (stmt == TSDBConstants.JNI_SQL_NULL) {
|
||||||
|
|
||||||
if (stmt == TSDBConstants.JNI_SQL_NULL) {
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL);
|
||||||
}
|
} else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
|
||||||
|
|
||||||
if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) {
|
|
||||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
|
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
from .connection import TDengineConnection
|
from .connection import TDengineConnection
|
||||||
from .cursor import TDengineCursor
|
from .cursor import TDengineCursor
|
||||||
|
|
||||||
|
# For some reason, the following is needed for VS Code (through PyLance) to
|
||||||
|
# recognize that "error" is a valid module of the "taos" package.
|
||||||
|
from .error import ProgrammingError
|
||||||
|
|
||||||
# Globals
|
# Globals
|
||||||
threadsafety = 0
|
threadsafety = 0
|
||||||
paramstyle = 'pyformat'
|
paramstyle = 'pyformat'
|
||||||
|
|
|
@ -437,6 +437,10 @@ static void cqProcessCreateTimer(void *param, void *tmrId) {
|
||||||
taosReleaseRef(cqObjRef, (int64_t)param);
|
taosReleaseRef(cqObjRef, (int64_t)param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inner implement in tscStream.c
|
||||||
|
TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* desName, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||||
|
int64_t stime, void *param, void (*callback)(void *));
|
||||||
|
|
||||||
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
||||||
pObj->pContext = pContext;
|
pObj->pContext = pContext;
|
||||||
|
|
||||||
|
@ -449,11 +453,10 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
||||||
pObj->tmrId = 0;
|
pObj->tmrId = 0;
|
||||||
|
|
||||||
if (pObj->pStream == NULL) {
|
if (pObj->pStream == NULL) {
|
||||||
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, INT64_MIN, (void *)pObj->rid, NULL);
|
pObj->pStream = taos_open_stream_withname(pContext->dbConn, pObj->dstTable, pObj->sqlStr, cqProcessStreamRes, INT64_MIN, (void *)pObj->rid, NULL);
|
||||||
|
|
||||||
// TODO the pObj->pStream may be released if error happens
|
// TODO the pObj->pStream may be released if error happens
|
||||||
if (pObj->pStream) {
|
if (pObj->pStream) {
|
||||||
tscSetStreamDestTable(pObj->pStream, pObj->dstTable);
|
|
||||||
pContext->num++;
|
pContext->num++;
|
||||||
cDebug("vgId:%d, id:%d CQ:%s is opened", pContext->vgId, pObj->tid, pObj->sqlStr);
|
cDebug("vgId:%d, id:%d CQ:%s is opened", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,8 +10,15 @@ INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc)
|
||||||
INCLUDE_DIRECTORIES(inc)
|
INCLUDE_DIRECTORIES(inc)
|
||||||
AUX_SOURCE_DIRECTORY(src SRC)
|
AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc")
|
||||||
|
ELSE ()
|
||||||
|
SET(LINK_JEMALLOC "")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
ADD_EXECUTABLE(taosd ${SRC})
|
ADD_EXECUTABLE(taosd ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync)
|
TARGET_LINK_LIBRARIES(taosd mnode monitor http tsdb twal vnode cJson lz4 balance sync ${LINK_JEMALLOC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosd taos_static)
|
TARGET_LINK_LIBRARIES(taosd taos_static)
|
||||||
|
|
|
@ -375,6 +375,8 @@ do { \
|
||||||
|
|
||||||
#define TSDB_MAX_WAL_SIZE (1024*1024*3)
|
#define TSDB_MAX_WAL_SIZE (1024*1024*3)
|
||||||
|
|
||||||
|
#define TSDB_ARB_DUMMY_TIME 4765104000000 // 2121-01-01 00:00:00.000, :P
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TAOS_QTYPE_RPC = 0,
|
TAOS_QTYPE_RPC = 0,
|
||||||
TAOS_QTYPE_FWD = 1,
|
TAOS_QTYPE_FWD = 1,
|
||||||
|
|
|
@ -215,11 +215,11 @@ int32_t* taosGetErrno();
|
||||||
#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit")
|
#define TSDB_CODE_VND_IS_FLOWCTRL TAOS_DEF_ERROR_CODE(0, 0x050C) //"Database memory is full for waiting commit")
|
||||||
#define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping")
|
#define TSDB_CODE_VND_IS_DROPPING TAOS_DEF_ERROR_CODE(0, 0x050D) //"Database is dropping")
|
||||||
#define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing")
|
#define TSDB_CODE_VND_IS_BALANCING TAOS_DEF_ERROR_CODE(0, 0x050E) //"Database is balancing")
|
||||||
|
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0510) //"Database is closing")
|
||||||
#define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended")
|
#define TSDB_CODE_VND_NOT_SYNCED TAOS_DEF_ERROR_CODE(0, 0x0511) //"Database suspended")
|
||||||
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")
|
#define TSDB_CODE_VND_NO_WRITE_AUTH TAOS_DEF_ERROR_CODE(0, 0x0512) //"Database write operation denied")
|
||||||
#define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing")
|
#define TSDB_CODE_VND_IS_SYNCING TAOS_DEF_ERROR_CODE(0, 0x0513) //"Database is syncing")
|
||||||
#define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state")
|
#define TSDB_CODE_VND_INVALID_TSDB_STATE TAOS_DEF_ERROR_CODE(0, 0x0514) //"Invalid tsdb state")
|
||||||
#define TSDB_CODE_VND_IS_CLOSING TAOS_DEF_ERROR_CODE(0, 0x0515) //"Database is closing")
|
|
||||||
|
|
||||||
// tsdb
|
// tsdb
|
||||||
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID")
|
#define TSDB_CODE_TDB_INVALID_TABLE_ID TAOS_DEF_ERROR_CODE(0, 0x0600) //"Invalid table ID")
|
||||||
|
|
|
@ -474,6 +474,7 @@ typedef struct {
|
||||||
bool simpleAgg;
|
bool simpleAgg;
|
||||||
bool pointInterpQuery; // point interpolation query
|
bool pointInterpQuery; // point interpolation query
|
||||||
bool needReverseScan; // need reverse scan
|
bool needReverseScan; // need reverse scan
|
||||||
|
bool stateWindow; // state window flag
|
||||||
|
|
||||||
STimeWindow window;
|
STimeWindow window;
|
||||||
int32_t numOfTables;
|
int32_t numOfTables;
|
||||||
|
|
|
@ -31,6 +31,8 @@ typedef struct {
|
||||||
#define TFS_UNDECIDED_ID -1
|
#define TFS_UNDECIDED_ID -1
|
||||||
#define TFS_PRIMARY_LEVEL 0
|
#define TFS_PRIMARY_LEVEL 0
|
||||||
#define TFS_PRIMARY_ID 0
|
#define TFS_PRIMARY_ID 0
|
||||||
|
#define TFS_MIN_LEVEL 0
|
||||||
|
#define TFS_MAX_LEVEL (TSDB_MAX_TIERS - 1)
|
||||||
|
|
||||||
// FS APIs ====================================
|
// FS APIs ====================================
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -409,6 +409,9 @@ void tsdbDecCommitRef(int vgId);
|
||||||
int tsdbSyncSend(void *pRepo, SOCKET socketFd);
|
int tsdbSyncSend(void *pRepo, SOCKET socketFd);
|
||||||
int tsdbSyncRecv(void *pRepo, SOCKET socketFd);
|
int tsdbSyncRecv(void *pRepo, SOCKET socketFd);
|
||||||
|
|
||||||
|
// For TSDB Compact
|
||||||
|
int tsdbCompact(STsdbRepo *pRepo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -136,76 +136,75 @@
|
||||||
#define TK_VARIABLE 117
|
#define TK_VARIABLE 117
|
||||||
#define TK_INTERVAL 118
|
#define TK_INTERVAL 118
|
||||||
#define TK_SESSION 119
|
#define TK_SESSION 119
|
||||||
#define TK_FILL 120
|
#define TK_STATE_WINDOW 120
|
||||||
#define TK_SLIDING 121
|
#define TK_FILL 121
|
||||||
#define TK_ORDER 122
|
#define TK_SLIDING 122
|
||||||
#define TK_BY 123
|
#define TK_ORDER 123
|
||||||
#define TK_ASC 124
|
#define TK_BY 124
|
||||||
#define TK_DESC 125
|
#define TK_ASC 125
|
||||||
#define TK_GROUP 126
|
#define TK_DESC 126
|
||||||
#define TK_HAVING 127
|
#define TK_GROUP 127
|
||||||
#define TK_LIMIT 128
|
#define TK_HAVING 128
|
||||||
#define TK_OFFSET 129
|
#define TK_LIMIT 129
|
||||||
#define TK_SLIMIT 130
|
#define TK_OFFSET 130
|
||||||
#define TK_SOFFSET 131
|
#define TK_SLIMIT 131
|
||||||
#define TK_WHERE 132
|
#define TK_SOFFSET 132
|
||||||
#define TK_NOW 133
|
#define TK_WHERE 133
|
||||||
#define TK_RESET 134
|
#define TK_NOW 134
|
||||||
#define TK_QUERY 135
|
#define TK_RESET 135
|
||||||
#define TK_SYNCDB 136
|
#define TK_QUERY 136
|
||||||
#define TK_ADD 137
|
#define TK_SYNCDB 137
|
||||||
#define TK_COLUMN 138
|
#define TK_ADD 138
|
||||||
#define TK_MODIFY 139
|
#define TK_COLUMN 139
|
||||||
#define TK_TAG 140
|
#define TK_MODIFY 140
|
||||||
#define TK_CHANGE 141
|
#define TK_TAG 141
|
||||||
#define TK_SET 142
|
#define TK_CHANGE 142
|
||||||
#define TK_KILL 143
|
#define TK_SET 143
|
||||||
#define TK_CONNECTION 144
|
#define TK_KILL 144
|
||||||
#define TK_STREAM 145
|
#define TK_CONNECTION 145
|
||||||
#define TK_COLON 146
|
#define TK_STREAM 146
|
||||||
#define TK_ABORT 147
|
#define TK_COLON 147
|
||||||
#define TK_AFTER 148
|
#define TK_ABORT 148
|
||||||
#define TK_ATTACH 149
|
#define TK_AFTER 149
|
||||||
#define TK_BEFORE 150
|
#define TK_ATTACH 150
|
||||||
#define TK_BEGIN 151
|
#define TK_BEFORE 151
|
||||||
#define TK_CASCADE 152
|
#define TK_BEGIN 152
|
||||||
#define TK_CLUSTER 153
|
#define TK_CASCADE 153
|
||||||
#define TK_CONFLICT 154
|
#define TK_CLUSTER 154
|
||||||
#define TK_COPY 155
|
#define TK_CONFLICT 155
|
||||||
#define TK_DEFERRED 156
|
#define TK_COPY 156
|
||||||
#define TK_DELIMITERS 157
|
#define TK_DEFERRED 157
|
||||||
#define TK_DETACH 158
|
#define TK_DELIMITERS 158
|
||||||
#define TK_EACH 159
|
#define TK_DETACH 159
|
||||||
#define TK_END 160
|
#define TK_EACH 160
|
||||||
#define TK_EXPLAIN 161
|
#define TK_END 161
|
||||||
#define TK_FAIL 162
|
#define TK_EXPLAIN 162
|
||||||
#define TK_FOR 163
|
#define TK_FAIL 163
|
||||||
#define TK_IGNORE 164
|
#define TK_FOR 164
|
||||||
#define TK_IMMEDIATE 165
|
#define TK_IGNORE 165
|
||||||
#define TK_INITIALLY 166
|
#define TK_IMMEDIATE 166
|
||||||
#define TK_INSTEAD 167
|
#define TK_INITIALLY 167
|
||||||
#define TK_MATCH 168
|
#define TK_INSTEAD 168
|
||||||
#define TK_KEY 169
|
#define TK_MATCH 169
|
||||||
#define TK_OF 170
|
#define TK_KEY 170
|
||||||
#define TK_RAISE 171
|
#define TK_OF 171
|
||||||
#define TK_REPLACE 172
|
#define TK_RAISE 172
|
||||||
#define TK_RESTRICT 173
|
#define TK_REPLACE 173
|
||||||
#define TK_ROW 174
|
#define TK_RESTRICT 174
|
||||||
#define TK_STATEMENT 175
|
#define TK_ROW 175
|
||||||
#define TK_TRIGGER 176
|
#define TK_STATEMENT 176
|
||||||
#define TK_VIEW 177
|
#define TK_TRIGGER 177
|
||||||
#define TK_SEMI 178
|
#define TK_VIEW 178
|
||||||
#define TK_NONE 179
|
#define TK_SEMI 179
|
||||||
#define TK_PREV 180
|
#define TK_NONE 180
|
||||||
#define TK_LINEAR 181
|
#define TK_PREV 181
|
||||||
#define TK_IMPORT 182
|
#define TK_LINEAR 182
|
||||||
#define TK_TBNAME 183
|
#define TK_IMPORT 183
|
||||||
#define TK_JOIN 184
|
#define TK_TBNAME 184
|
||||||
#define TK_INSERT 185
|
#define TK_JOIN 185
|
||||||
#define TK_INTO 186
|
#define TK_INSERT 186
|
||||||
#define TK_VALUES 187
|
#define TK_INTO 187
|
||||||
|
#define TK_VALUES 188
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,17 @@ IF (TD_LINUX)
|
||||||
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
|
LIST(REMOVE_ITEM SRC ./src/shellDarwin.c)
|
||||||
ADD_EXECUTABLE(shell ${SRC})
|
ADD_EXECUTABLE(shell ${SRC})
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc")
|
||||||
|
ELSE ()
|
||||||
|
SET(LINK_JEMALLOC "")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(shell taos_static)
|
TARGET_LINK_LIBRARIES(shell taos_static ${LINK_JEMALLOC})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(shell taos)
|
TARGET_LINK_LIBRARIES(shell taos ${LINK_JEMALLOC})
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
SET_TARGET_PROPERTIES(shell PROPERTIES OUTPUT_NAME taos)
|
||||||
|
|
|
@ -55,14 +55,21 @@ ENDIF ()
|
||||||
MESSAGE("TD_VERSION_NUMBER is:" ${TD_VERSION_NUMBER})
|
MESSAGE("TD_VERSION_NUMBER is:" ${TD_VERSION_NUMBER})
|
||||||
ADD_DEFINITIONS(-DTD_VERNUMBER="${TD_VERSION_NUMBER}")
|
ADD_DEFINITIONS(-DTD_VERNUMBER="${TD_VERSION_NUMBER}")
|
||||||
|
|
||||||
|
IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
|
||||||
|
ADD_DEFINITIONS(-DTD_JEMALLOC_ENABLED -I${CMAKE_BINARY_DIR}/build/include -L${CMAKE_BINARY_DIR}/build/lib -Wl,-rpath,${CMAKE_BINARY_DIR}/build/lib -ljemalloc)
|
||||||
|
SET(LINK_JEMALLOC "-L${CMAKE_BINARY_DIR}/build/lib -ljemalloc")
|
||||||
|
ELSE ()
|
||||||
|
SET(LINK_JEMALLOC "")
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX)
|
IF (TD_LINUX)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||||
|
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson ${LINK_JEMALLOC})
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson ${LINK_JEMALLOC})
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSEIF (TD_WINDOWS)
|
ELSEIF (TD_WINDOWS)
|
||||||
AUX_SOURCE_DIRECTORY(. SRC)
|
AUX_SOURCE_DIRECTORY(. SRC)
|
||||||
|
@ -71,7 +78,7 @@ ELSEIF (TD_WINDOWS)
|
||||||
IF (TD_SOMODE_STATIC)
|
IF (TD_SOMODE_STATIC)
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
TARGET_LINK_LIBRARIES(taosdemo taos_static cJson)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
TARGET_LINK_LIBRARIES(taosdemo taos cJson})
|
TARGET_LINK_LIBRARIES(taosdemo taos cJson)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSEIF (TD_DARWIN)
|
ELSEIF (TD_DARWIN)
|
||||||
# missing a few dependencies, such as <argp.h>
|
# missing a few dependencies, such as <argp.h>
|
||||||
|
|
|
@ -1060,6 +1060,13 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
|
||||||
newCfg.partitions = partitions;
|
newCfg.partitions = partitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// community version can only change daysToKeep
|
||||||
|
// but enterprise version can change all daysToKeep options
|
||||||
|
#ifndef _STORAGE
|
||||||
|
newCfg.daysToKeep1 = newCfg.daysToKeep;
|
||||||
|
newCfg.daysToKeep2 = newCfg.daysToKeep;
|
||||||
|
#endif
|
||||||
|
|
||||||
return newCfg;
|
return newCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -941,7 +941,7 @@ static int32_t mnodeRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int64_t *)pWrite = 0;
|
*(int64_t *)pWrite = tsArbOnlineTimestamp;
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
|
@ -656,8 +656,6 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
||||||
dnodeReportStep("mnode-sdb", stepDesc, 0);
|
dnodeReportStep("mnode-sdb", stepDesc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qtype == TAOS_QTYPE_QUERY) return sdbPerformDeleteAction(pHead, pTable);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&tsSdbMgmt.mutex);
|
pthread_mutex_lock(&tsSdbMgmt.mutex);
|
||||||
|
|
||||||
if (pHead->version == 0) {
|
if (pHead->version == 0) {
|
||||||
|
@ -721,13 +719,11 @@ static int32_t sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *
|
||||||
if (action == SDB_ACTION_INSERT) {
|
if (action == SDB_ACTION_INSERT) {
|
||||||
return sdbPerformInsertAction(pHead, pTable);
|
return sdbPerformInsertAction(pHead, pTable);
|
||||||
} else if (action == SDB_ACTION_DELETE) {
|
} else if (action == SDB_ACTION_DELETE) {
|
||||||
//if (qtype == TAOS_QTYPE_FWD) {
|
if (qtype == TAOS_QTYPE_FWD) {
|
||||||
// Drop database/stable may take a long time and cause a timeout, so we confirm first then reput it into queue
|
// Drop database/stable may take a long time and cause a timeout, so we confirm first
|
||||||
// sdbWriteFwdToQueue(1, hparam, TAOS_QTYPE_QUERY, unused);
|
syncConfirmForward(tsSdbMgmt.sync, pHead->version, TSDB_CODE_SUCCESS, false);
|
||||||
// return TSDB_CODE_SUCCESS;
|
}
|
||||||
//} else {
|
|
||||||
return sdbPerformDeleteAction(pHead, pTable);
|
return sdbPerformDeleteAction(pHead, pTable);
|
||||||
//}
|
|
||||||
} else if (action == SDB_ACTION_UPDATE) {
|
} else if (action == SDB_ACTION_UPDATE) {
|
||||||
return sdbPerformUpdateAction(pHead, pTable);
|
return sdbPerformUpdateAction(pHead, pTable);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1140,8 +1136,11 @@ static void *sdbWorkerFp(void *pWorker) {
|
||||||
sdbConfirmForward(1, pRow, pRow->code);
|
sdbConfirmForward(1, pRow, pRow->code);
|
||||||
} else {
|
} else {
|
||||||
if (qtype == TAOS_QTYPE_FWD) {
|
if (qtype == TAOS_QTYPE_FWD) {
|
||||||
|
int32_t action = pRow->pHead.msgType % 10;
|
||||||
|
if (action != SDB_ACTION_DELETE) {
|
||||||
syncConfirmForward(tsSdbMgmt.sync, pRow->pHead.version, pRow->code, false);
|
syncConfirmForward(tsSdbMgmt.sync, pRow->pHead.version, pRow->code, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sdbFreeFromQueue(pRow);
|
sdbFreeFromQueue(pRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TD_JEMALLOC_ENABLED
|
||||||
|
#include <jemalloc/jemalloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TAOS_ALLOC_MODE_DEFAULT = 0,
|
TAOS_ALLOC_MODE_DEFAULT = 0,
|
||||||
TAOS_ALLOC_MODE_RANDOM_FAIL = 1,
|
TAOS_ALLOC_MODE_RANDOM_FAIL = 1,
|
||||||
|
|
|
@ -189,6 +189,7 @@ typedef struct SQueryAttr {
|
||||||
bool pointInterpQuery; // point interpolation query
|
bool pointInterpQuery; // point interpolation query
|
||||||
bool needReverseScan; // need reverse scan
|
bool needReverseScan; // need reverse scan
|
||||||
bool distinctTag; // distinct tag query
|
bool distinctTag; // distinct tag query
|
||||||
|
bool stateWindow; // window State on sub/normal table
|
||||||
int32_t interBufSize; // intermediate buffer sizse
|
int32_t interBufSize; // intermediate buffer sizse
|
||||||
|
|
||||||
int32_t havingNum; // having expr number
|
int32_t havingNum; // having expr number
|
||||||
|
@ -296,6 +297,7 @@ enum OPERATOR_TYPE_E {
|
||||||
OP_Filter = 19,
|
OP_Filter = 19,
|
||||||
OP_Distinct = 20,
|
OP_Distinct = 20,
|
||||||
OP_Join = 21,
|
OP_Join = 21,
|
||||||
|
OP_StateWindow = 22,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct SOperatorInfo {
|
typedef struct SOperatorInfo {
|
||||||
|
@ -460,6 +462,16 @@ typedef struct SSWindowOperatorInfo {
|
||||||
int32_t start; // start row index
|
int32_t start; // start row index
|
||||||
} SSWindowOperatorInfo;
|
} SSWindowOperatorInfo;
|
||||||
|
|
||||||
|
typedef struct SStateWindowOperatorInfo {
|
||||||
|
SOptrBasicInfo binfo;
|
||||||
|
STimeWindow curWindow; // current time window
|
||||||
|
int32_t numOfRows; // number of rows
|
||||||
|
int32_t colIndex; // start row index
|
||||||
|
int32_t start;
|
||||||
|
char* prevData; // previous data
|
||||||
|
|
||||||
|
} SStateWindowOperatorInfo ;
|
||||||
|
|
||||||
typedef struct SDistinctOperatorInfo {
|
typedef struct SDistinctOperatorInfo {
|
||||||
SHashObj *pSet;
|
SHashObj *pSet;
|
||||||
SSDataBlock *pRes;
|
SSDataBlock *pRes;
|
||||||
|
@ -509,6 +521,7 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
|
||||||
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||||
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
||||||
int32_t numOfRows, void* merger, bool groupMix);
|
int32_t numOfRows, void* merger, bool groupMix);
|
||||||
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param);
|
||||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger);
|
||||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||||
|
|
|
@ -89,6 +89,10 @@ typedef struct SSessionWindowVal {
|
||||||
SStrToken gap;
|
SStrToken gap;
|
||||||
} SSessionWindowVal;
|
} SSessionWindowVal;
|
||||||
|
|
||||||
|
typedef struct SWindowStateVal {
|
||||||
|
SStrToken col;
|
||||||
|
} SWindowStateVal;
|
||||||
|
|
||||||
struct SRelationInfo;
|
struct SRelationInfo;
|
||||||
|
|
||||||
typedef struct SSqlNode {
|
typedef struct SSqlNode {
|
||||||
|
@ -100,6 +104,7 @@ typedef struct SSqlNode {
|
||||||
SArray *fillType; // fill type[optional], SArray<tVariantListItem>
|
SArray *fillType; // fill type[optional], SArray<tVariantListItem>
|
||||||
SIntervalVal interval; // (interval, interval_offset) [optional]
|
SIntervalVal interval; // (interval, interval_offset) [optional]
|
||||||
SSessionWindowVal sessionVal; // session window [optional]
|
SSessionWindowVal sessionVal; // session window [optional]
|
||||||
|
SWindowStateVal windowstateVal; // window_state(col) [optional]
|
||||||
SStrToken sliding; // sliding window [optional]
|
SStrToken sliding; // sliding window [optional]
|
||||||
SLimitVal limit; // limit offset [optional]
|
SLimitVal limit; // limit offset [optional]
|
||||||
SLimitVal slimit; // group limit offset [optional]
|
SLimitVal slimit; // group limit offset [optional]
|
||||||
|
@ -275,7 +280,7 @@ SArray *tSqlExprListAppend(SArray *pList, tSqlExpr *pNode, SStrToken *pDistinc
|
||||||
void tSqlExprListDestroy(SArray *pList);
|
void tSqlExprListDestroy(SArray *pList);
|
||||||
|
|
||||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *ps, SWindowStateVal *pw,
|
||||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving);
|
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *pgLimit, tSqlExpr *pHaving);
|
||||||
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
|
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right);
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,7 @@ typedef struct SQueryInfo {
|
||||||
bool hasFilter;
|
bool hasFilter;
|
||||||
bool onlyTagQuery;
|
bool onlyTagQuery;
|
||||||
bool orderProjectQuery;
|
bool orderProjectQuery;
|
||||||
|
bool stateWindow;
|
||||||
} SQueryInfo;
|
} SQueryInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -456,8 +456,8 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
|
||||||
//////////////////////// The SELECT statement /////////////////////////////////
|
//////////////////////// The SELECT statement /////////////////////////////////
|
||||||
%type select {SSqlNode*}
|
%type select {SSqlNode*}
|
||||||
%destructor select {destroySqlNode($$);}
|
%destructor select {destroySqlNode($$);}
|
||||||
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) windowstate_option(D) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
|
||||||
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G, N);
|
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &D, &S, F, &L, &G, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(A) ::= LP select(B) RP. {A = B;}
|
select(A) ::= LP select(B) RP. {A = B;}
|
||||||
|
@ -475,7 +475,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||||
// select client_version()
|
// select client_version()
|
||||||
// select server_state()
|
// select server_state()
|
||||||
select(A) ::= SELECT(T) selcollist(W). {
|
select(A) ::= SELECT(T) selcollist(W). {
|
||||||
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// selcollist is a list of expressions that are to become the return
|
// selcollist is a list of expressions that are to become the return
|
||||||
|
@ -558,6 +558,11 @@ session_option(X) ::= SESSION LP ids(V) cpxName(Z) COMMA tmvar(Y) RP. {
|
||||||
X.col = V;
|
X.col = V;
|
||||||
X.gap = Y;
|
X.gap = Y;
|
||||||
}
|
}
|
||||||
|
%type windowstate_option {SWindowStateVal}
|
||||||
|
windowstate_option(X) ::= . {X.col.n = 0;}
|
||||||
|
windowstate_option(X) ::= STATE_WINDOW LP ids(V) RP. {
|
||||||
|
X.col = V;
|
||||||
|
}
|
||||||
|
|
||||||
%type fill_opt {SArray*}
|
%type fill_opt {SArray*}
|
||||||
%destructor fill_opt {taosArrayDestroy($$);}
|
%destructor fill_opt {taosArrayDestroy($$);}
|
||||||
|
|
|
@ -2490,7 +2490,6 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) {
|
||||||
tmp += POINTER_BYTES * pCtx->param[0].i64;
|
tmp += POINTER_BYTES * pCtx->param[0].i64;
|
||||||
|
|
||||||
size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen;
|
size_t size = sizeof(tValuePair) + pCtx->tagInfo.tagsLen;
|
||||||
// assert(pCtx->param[0].i64 > 0);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->param[0].i64; ++i) {
|
for (int32_t i = 0; i < pCtx->param[0].i64; ++i) {
|
||||||
pTopBotInfo->res[i] = (tValuePair*) tmp;
|
pTopBotInfo->res[i] = (tValuePair*) tmp;
|
||||||
|
@ -2499,7 +2498,6 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) {
|
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) {
|
||||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
if (pResInfo == NULL) {
|
if (pResInfo == NULL) {
|
||||||
|
@ -2579,13 +2577,14 @@ static void top_function(SQLFunctionCtx *pCtx) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
for (int32_t i = 0; i < pCtx->size; ++i) {
|
||||||
char *data = GET_INPUT_DATA(pCtx, i);
|
char *data = GET_INPUT_DATA(pCtx, i);
|
||||||
TSKEY ts = GET_TS_DATA(pCtx, i);
|
|
||||||
|
|
||||||
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
notNullElems++;
|
notNullElems++;
|
||||||
|
|
||||||
|
// NOTE: Set the default timestamp if it is missing [todo refactor]
|
||||||
|
TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0;
|
||||||
do_top_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
do_top_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2658,13 +2657,13 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pCtx->size; ++i) {
|
for (int32_t i = 0; i < pCtx->size; ++i) {
|
||||||
char *data = GET_INPUT_DATA(pCtx, i);
|
char *data = GET_INPUT_DATA(pCtx, i);
|
||||||
TSKEY ts = GET_TS_DATA(pCtx, i);
|
|
||||||
|
|
||||||
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
if (pCtx->hasNull && isNull(data, pCtx->inputType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
notNullElems++;
|
notNullElems++;
|
||||||
|
// NOTE: Set the default timestamp if it is missing [todo refactor]
|
||||||
|
TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0;
|
||||||
do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64, data, ts, pCtx->inputType, &pCtx->tagInfo, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2742,7 +2741,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
if (pCtx->param[1].i64 == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||||
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
||||||
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||||
} else if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
} else /*if (pCtx->param[1].i64 > PRIMARYKEY_TIMESTAMP_COL_INDEX)*/ {
|
||||||
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
__compar_fn_t comparator = (pCtx->param[2].i64 == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
||||||
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
qsort(tvp, (size_t)pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||||
}
|
}
|
||||||
|
@ -3299,8 +3298,12 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
|
||||||
if (pCtx->numOfParams == 2) {
|
if (pCtx->numOfParams == 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (pCtx->param[0].i64 == 1) {
|
||||||
|
SET_VAL(pCtx, pCtx->size, 1);
|
||||||
|
} else {
|
||||||
INC_INIT_VAL(pCtx, pCtx->size);
|
INC_INIT_VAL(pCtx, pCtx->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char *pData = GET_INPUT_DATA_LIST(pCtx);
|
char *pData = GET_INPUT_DATA_LIST(pCtx);
|
||||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||||
|
|
|
@ -189,12 +189,16 @@ static void destroySFillOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
static void destroyGroupbyOperatorInfo(void* param, int32_t numOfOutput);
|
static void destroyGroupbyOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
static void destroyArithOperatorInfo(void* param, int32_t numOfOutput);
|
static void destroyArithOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput);
|
static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
|
static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
|
static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
|
static void destroyAggOperatorInfo(void* param, int32_t numOfOutput);
|
||||||
static void destroyOperatorInfo(SOperatorInfo* pOperator);
|
static void destroyOperatorInfo(SOperatorInfo* pOperator);
|
||||||
|
|
||||||
|
|
||||||
static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock);
|
static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo, int32_t orderType, SSDataBlock* pBlock);
|
||||||
|
|
||||||
static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock);
|
static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pDataBlock);
|
||||||
static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOperatorInfo *pInfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex);
|
static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binf, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex);
|
||||||
|
|
||||||
static void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size);
|
static void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size);
|
||||||
static void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win);
|
static void getAlignQueryTimeWindow(SQueryAttr *pQueryAttr, int64_t key, int64_t keyFirst, int64_t keyLast, STimeWindow *win);
|
||||||
|
@ -731,7 +735,6 @@ static void doApplyFunctions(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx
|
||||||
if (pCtx[k].preAggVals.isSet && forwardStep < numOfTotal) {
|
if (pCtx[k].preAggVals.isSet && forwardStep < numOfTotal) {
|
||||||
pCtx[k].preAggVals.isSet = false;
|
pCtx[k].preAggVals.isSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) {
|
if (functionNeedToExecute(pRuntimeEnv, &pCtx[k], functionId)) {
|
||||||
aAggs[functionId].xFunction(&pCtx[k]);
|
aAggs[functionId].xFunction(&pCtx[k]);
|
||||||
}
|
}
|
||||||
|
@ -947,7 +950,13 @@ static void doSetInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx,
|
||||||
uint32_t status = aAggs[pCtx[i].functionId].status;
|
uint32_t status = aAggs[pCtx[i].functionId].status;
|
||||||
if ((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) {
|
if ((status & (TSDB_FUNCSTATE_SELECTIVITY | TSDB_FUNCSTATE_NEED_TS)) != 0) {
|
||||||
SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
SColumnInfoData* tsInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||||
|
// In case of the top/bottom query again the nest query result, which has no timestamp column
|
||||||
|
// don't set the ptsList attribute.
|
||||||
|
if (tsInfo->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||||
pCtx[i].ptsList = (int64_t*) tsInfo->pData;
|
pCtx[i].ptsList = (int64_t*) tsInfo->pData;
|
||||||
|
} else {
|
||||||
|
pCtx[i].ptsList = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) {
|
} else if (TSDB_COL_IS_UD_COL(pCol->flag) && (pOperator->pRuntimeEnv->scanFlag == MERGE_STAGE)) {
|
||||||
SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo;
|
SColIndex* pColIndex = &pOperator->pExpr[i].base.colInfo;
|
||||||
|
@ -1299,7 +1308,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ret =
|
int32_t ret =
|
||||||
setGroupResultOutputBuf(pRuntimeEnv, pInfo, pOperator->numOfOutput, val, type, bytes, item->groupIndex);
|
setGroupResultOutputBuf(pRuntimeEnv, &(pInfo->binfo), pOperator->numOfOutput, val, type, bytes, item->groupIndex);
|
||||||
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -1338,12 +1347,16 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInf
|
||||||
pInfo->start = j;
|
pInfo->start = j;
|
||||||
} else if (tsList[j] - pInfo->prevTs <= gap) {
|
} else if (tsList[j] - pInfo->prevTs <= gap) {
|
||||||
pInfo->curWindow.ekey = tsList[j];
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
pInfo->prevTs = tsList[j];
|
//pInfo->prevTs = tsList[j];
|
||||||
pInfo->numOfRows += 1;
|
pInfo->numOfRows += 1;
|
||||||
pInfo->start = j;
|
if (j == 0 && pInfo->start != 0) {
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->start = 0;
|
||||||
|
}
|
||||||
} else { // start a new session window
|
} else { // start a new session window
|
||||||
SResultRow* pResult = NULL;
|
SResultRow* pResult = NULL;
|
||||||
|
|
||||||
|
pInfo->curWindow.ekey = pInfo->curWindow.skey;
|
||||||
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
||||||
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
||||||
pBInfo->rowCellInfoOffset);
|
pBInfo->rowCellInfoOffset);
|
||||||
|
@ -1364,6 +1377,7 @@ static void doSessionWindowAggImpl(SOperatorInfo* pOperator, SSWindowOperatorInf
|
||||||
|
|
||||||
SResultRow* pResult = NULL;
|
SResultRow* pResult = NULL;
|
||||||
|
|
||||||
|
pInfo->curWindow.ekey = pInfo->curWindow.skey;
|
||||||
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
||||||
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
||||||
pBInfo->rowCellInfoOffset);
|
pBInfo->rowCellInfoOffset);
|
||||||
|
@ -1391,12 +1405,12 @@ static void setResultRowKey(SResultRow* pResultRow, char* pData, int16_t type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SGroupbyOperatorInfo *pInfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) {
|
static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SOptrBasicInfo *binfo, int32_t numOfCols, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) {
|
||||||
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
|
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
|
||||||
|
|
||||||
int32_t *rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
int32_t *rowCellInfoOffset = binfo->rowCellInfoOffset;
|
||||||
SResultRowInfo *pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
SResultRowInfo *pResultRowInfo = &binfo->resultRowInfo;
|
||||||
SQLFunctionCtx *pCtx = pInfo->binfo.pCtx;
|
SQLFunctionCtx *pCtx = binfo->pCtx;
|
||||||
|
|
||||||
// not assign result buffer yet, add new result buffer, TODO remove it
|
// not assign result buffer yet, add new result buffer, TODO remove it
|
||||||
char* d = pData;
|
char* d = pData;
|
||||||
|
@ -1767,6 +1781,11 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_StateWindow: {
|
||||||
|
pRuntimeEnv->proot = createStatewindowOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot, pQueryAttr->pExpr1, pQueryAttr->numOfOutput);
|
||||||
|
setTableScanFilterOperatorInfo(pRuntimeEnv->proot->upstream[0]->info, pRuntimeEnv->proot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case OP_Limit: {
|
case OP_Limit: {
|
||||||
pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot);
|
pRuntimeEnv->proot = createLimitOperatorInfo(pRuntimeEnv, pRuntimeEnv->proot);
|
||||||
|
@ -2109,6 +2128,8 @@ static bool onlyFirstQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQu
|
||||||
|
|
||||||
static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); }
|
static bool onlyLastQuery(SQueryAttr *pQueryAttr) { return onlyOneQueryType(pQueryAttr, TSDB_FUNC_LAST, TSDB_FUNC_LAST_DST); }
|
||||||
|
|
||||||
|
static bool notContainSessionOrStateWindow(SQueryAttr *pQueryAttr) { return !(pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow); }
|
||||||
|
|
||||||
static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) {
|
static int32_t updateBlockLoadStatus(SQueryAttr *pQuery, int32_t status) {
|
||||||
bool hasFirstLastFunc = false;
|
bool hasFirstLastFunc = false;
|
||||||
bool hasOtherFunc = false;
|
bool hasOtherFunc = false;
|
||||||
|
@ -2212,7 +2233,7 @@ static void changeExecuteScanOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
pQueryAttr->order.order = TSDB_ORDER_ASC;
|
pQueryAttr->order.order = TSDB_ORDER_ASC;
|
||||||
} else if (onlyLastQuery(pQueryAttr)) {
|
} else if (onlyLastQuery(pQueryAttr) && notContainSessionOrStateWindow(pQueryAttr)) {
|
||||||
if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||||
qDebug(msg, pQInfo, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
|
qDebug(msg, pQInfo, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
|
||||||
pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||||
|
@ -3204,7 +3225,7 @@ void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResult
|
||||||
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr *pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
|
|
||||||
int32_t numOfOutput = pOperator->numOfOutput;
|
int32_t numOfOutput = pOperator->numOfOutput;
|
||||||
if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0) {
|
if (pQueryAttr->groupbyColumn || QUERY_IS_INTERVAL_QUERY(pQueryAttr) || pQueryAttr->sw.gap > 0 || pQueryAttr->stateWindow) {
|
||||||
// for each group result, call the finalize function for each column
|
// for each group result, call the finalize function for each column
|
||||||
if (pQueryAttr->groupbyColumn) {
|
if (pQueryAttr->groupbyColumn) {
|
||||||
closeAllResultRows(pResultRowInfo);
|
closeAllResultRows(pResultRowInfo);
|
||||||
|
@ -4213,6 +4234,10 @@ static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBl
|
||||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
|
int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||||
pTableQueryInfo->lastKey = ((order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey) + step;
|
pTableQueryInfo->lastKey = ((order == TSDB_ORDER_ASC)? pBlock->info.window.ekey:pBlock->info.window.skey) + step;
|
||||||
|
|
||||||
|
if (pTableQueryInfo->pTable == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
STableIdInfo tidInfo = createTableIdInfo(pTableQueryInfo);
|
STableIdInfo tidInfo = createTableIdInfo(pTableQueryInfo);
|
||||||
STableIdInfo *idinfo = taosHashGet(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid));
|
STableIdInfo *idinfo = taosHashGet(pTableIdInfo, &tidInfo.tid, sizeof(tidInfo.tid));
|
||||||
if (idinfo != NULL) {
|
if (idinfo != NULL) {
|
||||||
|
@ -4514,6 +4539,12 @@ void setTableScanFilterOperatorInfo(STableScanInfo* pTableScanInfo, SOperatorInf
|
||||||
} else if (pDownstream->operatorType == OP_SessionWindow) {
|
} else if (pDownstream->operatorType == OP_SessionWindow) {
|
||||||
SSWindowOperatorInfo* pInfo = pDownstream->info;
|
SSWindowOperatorInfo* pInfo = pDownstream->info;
|
||||||
|
|
||||||
|
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
||||||
|
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
||||||
|
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
||||||
|
} else if (pDownstream->operatorType == OP_StateWindow) {
|
||||||
|
SStateWindowOperatorInfo* pInfo = pDownstream->info;
|
||||||
|
|
||||||
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
pTableScanInfo->pCtx = pInfo->binfo.pCtx;
|
||||||
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
pTableScanInfo->pResultRowInfo = &pInfo->binfo.resultRowInfo;
|
||||||
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
pTableScanInfo->rowCellInfoOffset = pInfo->binfo.rowCellInfoOffset;
|
||||||
|
@ -4625,7 +4656,6 @@ static void destroyGlobalAggOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
tfree(pInfo->prevRow);
|
tfree(pInfo->prevRow);
|
||||||
tfree(pInfo->currentGroupColData);
|
tfree(pInfo->currentGroupColData);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) {
|
static void destroySlimitOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
SSLimitOperatorInfo *pInfo = (SSLimitOperatorInfo*) param;
|
SSLimitOperatorInfo *pInfo = (SSLimitOperatorInfo*) param;
|
||||||
taosArrayDestroy(pInfo->orderColumnList);
|
taosArrayDestroy(pInfo->orderColumnList);
|
||||||
|
@ -4885,8 +4915,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) {
|
||||||
updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows);
|
updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows);
|
||||||
|
|
||||||
arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput);
|
arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput);
|
||||||
|
if (pTableQueryInfo != NULL) {
|
||||||
if (pTableQueryInfo != NULL) { // TODO refactor
|
|
||||||
updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order);
|
updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4929,8 +4958,7 @@ static SSDataBlock* doArithmeticOperation(void* param, bool* newgroup) {
|
||||||
updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows);
|
updateOutputBuf(&pArithInfo->binfo, &pArithInfo->bufCapacity, pBlock->info.rows);
|
||||||
|
|
||||||
arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput);
|
arithmeticApplyFunctions(pRuntimeEnv, pInfo->pCtx, pOperator->numOfOutput);
|
||||||
|
if (pTableQueryInfo != NULL) {
|
||||||
if (pTableQueryInfo != NULL) { // TODO refactor
|
|
||||||
updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order);
|
updateTableIdInfo(pTableQueryInfo, pBlock, pRuntimeEnv->pTableRetrieveTsMap, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5131,13 +5159,83 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) {
|
||||||
return pIntervalInfo->pRes;
|
return pIntervalInfo->pRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) {
|
|
||||||
|
static void doStateWindowAggImpl(SOperatorInfo* pOperator, SStateWindowOperatorInfo *pInfo, SSDataBlock *pSDataBlock) {
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
STableQueryInfo* item = pRuntimeEnv->current;
|
||||||
|
SColumnInfoData* pColInfoData = taosArrayGet(pSDataBlock->pDataBlock, pInfo->colIndex);
|
||||||
|
|
||||||
|
SOptrBasicInfo* pBInfo = &pInfo->binfo;
|
||||||
|
|
||||||
|
bool masterScan = IS_MASTER_SCAN(pRuntimeEnv);
|
||||||
|
int16_t bytes = pColInfoData->info.bytes;
|
||||||
|
int16_t type = pColInfoData->info.type;
|
||||||
|
|
||||||
|
SColumnInfoData* pTsColInfoData = taosArrayGet(pSDataBlock->pDataBlock, 0);
|
||||||
|
TSKEY* tsList = (TSKEY*)pTsColInfoData->pData;
|
||||||
|
|
||||||
|
pInfo->numOfRows = 0;
|
||||||
|
for (int32_t j = 0; j < pSDataBlock->info.rows; ++j) {
|
||||||
|
char* val = ((char*)pColInfoData->pData) + bytes * j;
|
||||||
|
if (isNull(val, type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pInfo->prevData == NULL) {
|
||||||
|
pInfo->prevData = malloc(bytes);
|
||||||
|
memcpy(pInfo->prevData, val, bytes);
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->curWindow.skey = tsList[j];
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
pInfo->start = j;
|
||||||
|
|
||||||
|
} else if (memcmp(pInfo->prevData, val, bytes) == 0) {
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
pInfo->numOfRows += 1;
|
||||||
|
//pInfo->start = j;
|
||||||
|
if (j == 0 && pInfo->start != 0) {
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->start = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SResultRow* pResult = NULL;
|
||||||
|
pInfo->curWindow.ekey = pInfo->curWindow.skey;
|
||||||
|
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
||||||
|
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
||||||
|
pBInfo->rowCellInfoOffset);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList,
|
||||||
|
pSDataBlock->info.rows, pOperator->numOfOutput);
|
||||||
|
|
||||||
|
pInfo->curWindow.skey = tsList[j];
|
||||||
|
pInfo->curWindow.ekey = tsList[j];
|
||||||
|
memcpy(pInfo->prevData, val, bytes);
|
||||||
|
pInfo->numOfRows = 1;
|
||||||
|
pInfo->start = j;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SResultRow* pResult = NULL;
|
||||||
|
|
||||||
|
pInfo->curWindow.ekey = pInfo->curWindow.skey;
|
||||||
|
int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, &pBInfo->resultRowInfo, &pInfo->curWindow, masterScan,
|
||||||
|
&pResult, item->groupIndex, pBInfo->pCtx, pOperator->numOfOutput,
|
||||||
|
pBInfo->rowCellInfoOffset);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
|
||||||
|
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
doApplyFunctions(pRuntimeEnv, pBInfo->pCtx, &pInfo->curWindow, pInfo->start, pInfo->numOfRows, tsList,
|
||||||
|
pSDataBlock->info.rows, pOperator->numOfOutput);
|
||||||
|
}
|
||||||
|
static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) {
|
||||||
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
if (pOperator->status == OP_EXEC_DONE) {
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSWindowOperatorInfo* pWindowInfo = pOperator->info;
|
SStateWindowOperatorInfo* pWindowInfo = pOperator->info;
|
||||||
SOptrBasicInfo* pBInfo = &pWindowInfo->binfo;
|
SOptrBasicInfo* pBInfo = &pWindowInfo->binfo;
|
||||||
|
|
||||||
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
@ -5154,6 +5252,62 @@ static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) {
|
||||||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
int32_t order = pQueryAttr->order.order;
|
int32_t order = pQueryAttr->order.order;
|
||||||
STimeWindow win = pQueryAttr->window;
|
STimeWindow win = pQueryAttr->window;
|
||||||
|
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||||
|
while (1) {
|
||||||
|
SSDataBlock* pBlock = upstream->exec(upstream, newgroup);
|
||||||
|
if (pBlock == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setInputDataBlock(pOperator, pBInfo->pCtx, pBlock, pQueryAttr->order.order);
|
||||||
|
if (pWindowInfo->colIndex == -1) {
|
||||||
|
pWindowInfo->colIndex = getGroupbyColumnIndex(pRuntimeEnv->pQueryAttr->pGroupbyExpr, pBlock);
|
||||||
|
}
|
||||||
|
doStateWindowAggImpl(pOperator, pWindowInfo, pBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore the value
|
||||||
|
pQueryAttr->order.order = order;
|
||||||
|
pQueryAttr->window = win;
|
||||||
|
|
||||||
|
pOperator->status = OP_RES_TO_RETURN;
|
||||||
|
closeAllResultRows(&pBInfo->resultRowInfo);
|
||||||
|
setQueryStatus(pRuntimeEnv, QUERY_COMPLETED);
|
||||||
|
finalizeQueryResult(pOperator, pBInfo->pCtx, &pBInfo->resultRowInfo, pBInfo->rowCellInfoOffset);
|
||||||
|
|
||||||
|
initGroupResInfo(&pRuntimeEnv->groupResInfo, &pBInfo->resultRowInfo);
|
||||||
|
toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes);
|
||||||
|
|
||||||
|
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBInfo->pRes->info.rows == 0? NULL:pBInfo->pRes;
|
||||||
|
}
|
||||||
|
static SSDataBlock* doSessionWindowAgg(void* param, bool* newgroup) {
|
||||||
|
SOperatorInfo* pOperator = (SOperatorInfo*) param;
|
||||||
|
if (pOperator->status == OP_EXEC_DONE) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSWindowOperatorInfo* pWindowInfo = pOperator->info;
|
||||||
|
SOptrBasicInfo* pBInfo = &pWindowInfo->binfo;
|
||||||
|
|
||||||
|
|
||||||
|
SQueryRuntimeEnv* pRuntimeEnv = pOperator->pRuntimeEnv;
|
||||||
|
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||||
|
toSSDataBlock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pBInfo->pRes);
|
||||||
|
|
||||||
|
if (pBInfo->pRes->info.rows == 0 || !hasRemainDataInCurrentGroup(&pRuntimeEnv->groupResInfo)) {
|
||||||
|
pOperator->status = OP_EXEC_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pBInfo->pRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||||
|
//pQueryAttr->order.order = TSDB_ORDER_ASC;
|
||||||
|
int32_t order = pQueryAttr->order.order;
|
||||||
|
STimeWindow win = pQueryAttr->window;
|
||||||
|
|
||||||
SOperatorInfo* upstream = pOperator->upstream[0];
|
SOperatorInfo* upstream = pOperator->upstream[0];
|
||||||
|
|
||||||
|
@ -5389,7 +5543,7 @@ SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOpera
|
||||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
|
||||||
pOperator->exec = doAggregate;
|
pOperator->exec = doAggregate;
|
||||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
pOperator->cleanup = destroyAggOperatorInfo;
|
||||||
appendUpstream(pOperator, upstream);
|
appendUpstream(pOperator, upstream);
|
||||||
|
|
||||||
return pOperator;
|
return pOperator;
|
||||||
|
@ -5409,6 +5563,19 @@ static void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
SOptrBasicInfo* pInfo = (SOptrBasicInfo*) param;
|
SOptrBasicInfo* pInfo = (SOptrBasicInfo*) param;
|
||||||
doDestroyBasicInfo(pInfo, numOfOutput);
|
doDestroyBasicInfo(pInfo, numOfOutput);
|
||||||
}
|
}
|
||||||
|
static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
|
SStateWindowOperatorInfo* pInfo = (SStateWindowOperatorInfo*) param;
|
||||||
|
doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
|
||||||
|
tfree(pInfo->prevData);
|
||||||
|
}
|
||||||
|
static void destroyAggOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
|
SAggOperatorInfo* pInfo = (SAggOperatorInfo*) param;
|
||||||
|
doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
|
||||||
|
}
|
||||||
|
static void destroySWindowOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
|
SSWindowOperatorInfo* pInfo = (SSWindowOperatorInfo*) param;
|
||||||
|
doDestroyBasicInfo(&pInfo->binfo, numOfOutput);
|
||||||
|
}
|
||||||
|
|
||||||
static void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
|
static void destroySFillOperatorInfo(void* param, int32_t numOfOutput) {
|
||||||
SFillOperatorInfo* pInfo = (SFillOperatorInfo*) param;
|
SFillOperatorInfo* pInfo = (SFillOperatorInfo*) param;
|
||||||
|
@ -5463,7 +5630,7 @@ SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SO
|
||||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
|
||||||
pOperator->exec = doSTableAggregate;
|
pOperator->exec = doSTableAggregate;
|
||||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
pOperator->cleanup = destroyAggOperatorInfo;
|
||||||
appendUpstream(pOperator, upstream);
|
appendUpstream(pOperator, upstream);
|
||||||
|
|
||||||
return pOperator;
|
return pOperator;
|
||||||
|
@ -5589,7 +5756,29 @@ SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOp
|
||||||
appendUpstream(pOperator, upstream);
|
appendUpstream(pOperator, upstream);
|
||||||
return pOperator;
|
return pOperator;
|
||||||
}
|
}
|
||||||
|
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
|
SStateWindowOperatorInfo* pInfo = calloc(1, sizeof(SStateWindowOperatorInfo));
|
||||||
|
pInfo->colIndex = -1;
|
||||||
|
pInfo->binfo.pCtx = createSQLFunctionCtx(pRuntimeEnv, pExpr, numOfOutput, &pInfo->binfo.rowCellInfoOffset);
|
||||||
|
pInfo->binfo.pRes = createOutputBuf(pExpr, numOfOutput, pRuntimeEnv->resultInfo.capacity);
|
||||||
|
initResultRowInfo(&pInfo->binfo.resultRowInfo, 8, TSDB_DATA_TYPE_INT);
|
||||||
|
|
||||||
|
SOperatorInfo* pOperator = calloc(1, sizeof(SOperatorInfo));
|
||||||
|
pOperator->name = "StateWindowOperator";
|
||||||
|
pOperator->operatorType = OP_StateWindow;
|
||||||
|
pOperator->blockingOptr = true;
|
||||||
|
pOperator->status = OP_IN_EXECUTING;
|
||||||
|
pOperator->pExpr = pExpr;
|
||||||
|
pOperator->numOfOutput = numOfOutput;
|
||||||
|
pOperator->info = pInfo;
|
||||||
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
|
pOperator->exec = doStateWindowAgg;
|
||||||
|
pOperator->cleanup = destroyStateWindowOperatorInfo;
|
||||||
|
|
||||||
|
appendUpstream(pOperator, upstream);
|
||||||
|
return pOperator;
|
||||||
|
|
||||||
|
}
|
||||||
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||||
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
SSWindowOperatorInfo* pInfo = calloc(1, sizeof(SSWindowOperatorInfo));
|
||||||
|
|
||||||
|
@ -5609,7 +5798,7 @@ SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperato
|
||||||
pOperator->info = pInfo;
|
pOperator->info = pInfo;
|
||||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||||
pOperator->exec = doSessionWindowAgg;
|
pOperator->exec = doSessionWindowAgg;
|
||||||
pOperator->cleanup = destroyBasicOperatorInfo;
|
pOperator->cleanup = destroySWindowOperatorInfo;
|
||||||
|
|
||||||
appendUpstream(pOperator, upstream);
|
appendUpstream(pOperator, upstream);
|
||||||
return pOperator;
|
return pOperator;
|
||||||
|
@ -6901,6 +7090,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
|
||||||
pQueryAttr->simpleAgg = pQueryMsg->simpleAgg;
|
pQueryAttr->simpleAgg = pQueryMsg->simpleAgg;
|
||||||
pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery;
|
pQueryAttr->pointInterpQuery = pQueryMsg->pointInterpQuery;
|
||||||
pQueryAttr->needReverseScan = pQueryMsg->needReverseScan;
|
pQueryAttr->needReverseScan = pQueryMsg->needReverseScan;
|
||||||
|
pQueryAttr->stateWindow = pQueryMsg->stateWindow;
|
||||||
pQueryAttr->vgId = vgId;
|
pQueryAttr->vgId = vgId;
|
||||||
|
|
||||||
pQueryAttr->tableCols = calloc(numOfCols, sizeof(SSingleColumnFilterInfo));
|
pQueryAttr->tableCols = calloc(numOfCols, sizeof(SSingleColumnFilterInfo));
|
||||||
|
|
|
@ -592,6 +592,14 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
||||||
op = OP_SessionWindow;
|
op = OP_SessionWindow;
|
||||||
taosArrayPush(plan, &op);
|
taosArrayPush(plan, &op);
|
||||||
|
|
||||||
|
if (pQueryAttr->pExpr2 != NULL) {
|
||||||
|
op = OP_Arithmetic;
|
||||||
|
taosArrayPush(plan, &op);
|
||||||
|
}
|
||||||
|
} else if (pQueryAttr->stateWindow) {
|
||||||
|
op = OP_StateWindow;
|
||||||
|
taosArrayPush(plan, &op);
|
||||||
|
|
||||||
if (pQueryAttr->pExpr2 != NULL) {
|
if (pQueryAttr->pExpr2 != NULL) {
|
||||||
op = OP_Arithmetic;
|
op = OP_Arithmetic;
|
||||||
taosArrayPush(plan, &op);
|
taosArrayPush(plan, &op);
|
||||||
|
|
|
@ -726,9 +726,9 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
||||||
* extract the select info out of sql string
|
* extract the select info out of sql string
|
||||||
*/
|
*/
|
||||||
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelationInfo *pFrom, tSqlExpr *pWhere,
|
||||||
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval, SSessionWindowVal *pSession,
|
SArray *pGroupby, SArray *pSortOrder, SIntervalVal *pInterval,
|
||||||
SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit, SLimitVal *psLimit,
|
SSessionWindowVal *pSession, SWindowStateVal *pWindowStateVal, SStrToken *pSliding, SArray *pFill, SLimitVal *pLimit,
|
||||||
tSqlExpr *pHaving) {
|
SLimitVal *psLimit, tSqlExpr *pHaving) {
|
||||||
assert(pSelNodeList != NULL);
|
assert(pSelNodeList != NULL);
|
||||||
|
|
||||||
SSqlNode *pSqlNode = calloc(1, sizeof(SSqlNode));
|
SSqlNode *pSqlNode = calloc(1, sizeof(SSqlNode));
|
||||||
|
@ -779,6 +779,12 @@ SSqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelNodeList, SRelat
|
||||||
TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col);
|
TPARSER_SET_NONE_TOKEN(pSqlNode->sessionVal.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pWindowStateVal != NULL) {
|
||||||
|
pSqlNode->windowstateVal = *pWindowStateVal;
|
||||||
|
} else {
|
||||||
|
TPARSER_SET_NONE_TOKEN(pSqlNode->windowstateVal.col);
|
||||||
|
}
|
||||||
|
|
||||||
return pSqlNode;
|
return pSqlNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2547
src/query/src/sql.c
2547
src/query/src/sql.c
File diff suppressed because it is too large
Load Diff
|
@ -1150,7 +1150,12 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
||||||
pPeer->peerFd = connFd;
|
pPeer->peerFd = connFd;
|
||||||
pPeer->role = TAOS_SYNC_ROLE_UNSYNCED;
|
pPeer->role = TAOS_SYNC_ROLE_UNSYNCED;
|
||||||
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer->rid, connFd);
|
pPeer->pConn = syncAllocateTcpConn(tsTcpPool, pPeer->rid, connFd);
|
||||||
if (pPeer->isArb) tsArbOnline = 1;
|
if (pPeer->isArb) {
|
||||||
|
tsArbOnline = 1;
|
||||||
|
if (tsArbOnlineTimestamp == TSDB_ARB_DUMMY_TIME) {
|
||||||
|
tsArbOnlineTimestamp = taosGetTimestampMs();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sDebug("%s, failed to setup peer connection to server since %s, try later", pPeer->id, strerror(errno));
|
sDebug("%s, failed to setup peer connection to server since %s, try later", pPeer->id, strerror(errno));
|
||||||
taosCloseSocket(connFd);
|
taosCloseSocket(connFd);
|
||||||
|
|
|
@ -6,6 +6,10 @@ AUX_SOURCE_DIRECTORY(src SRC)
|
||||||
ADD_LIBRARY(tsdb ${SRC})
|
ADD_LIBRARY(tsdb ${SRC})
|
||||||
TARGET_LINK_LIBRARIES(tsdb tfs common tutil)
|
TARGET_LINK_LIBRARIES(tsdb tfs common tutil)
|
||||||
|
|
||||||
|
IF (TD_TSDB_PLUGINS)
|
||||||
|
TARGET_LINK_LIBRARIES(tsdb tsdbPlugins)
|
||||||
|
ENDIF ()
|
||||||
|
|
||||||
IF (TD_LINUX)
|
IF (TD_LINUX)
|
||||||
# Someone has no gtest directory, so comment it
|
# Someone has no gtest directory, so comment it
|
||||||
# ADD_SUBDIRECTORY(tests)
|
# ADD_SUBDIRECTORY(tests)
|
||||||
|
|
|
@ -29,10 +29,17 @@ typedef struct {
|
||||||
int64_t size;
|
int64_t size;
|
||||||
} SKVRecord;
|
} SKVRecord;
|
||||||
|
|
||||||
|
#define TSDB_DEFAULT_BLOCK_ROWS(maxRows) ((maxRows)*4 / 5)
|
||||||
|
|
||||||
void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn);
|
void tsdbGetRtnSnap(STsdbRepo *pRepo, SRtn *pRtn);
|
||||||
int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord);
|
int tsdbEncodeKVRecord(void **buf, SKVRecord *pRecord);
|
||||||
void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord);
|
void *tsdbDecodeKVRecord(void *buf, SKVRecord *pRecord);
|
||||||
void *tsdbCommitData(STsdbRepo *pRepo);
|
void *tsdbCommitData(STsdbRepo *pRepo);
|
||||||
|
int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn);
|
||||||
|
int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf, SBlockIdx *pIdx);
|
||||||
|
int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf);
|
||||||
|
int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock,
|
||||||
|
bool isLast, bool isSuper, void **ppBuf, void **ppCBuf);
|
||||||
int tsdbApplyRtn(STsdbRepo *pRepo);
|
int tsdbApplyRtn(STsdbRepo *pRepo);
|
||||||
|
|
||||||
static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) {
|
static FORCE_INLINE int tsdbGetFidLevel(int fid, SRtn *pRtn) {
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#ifndef _TD_TSDB_COMMIT_QUEUE_H_
|
#ifndef _TD_TSDB_COMMIT_QUEUE_H_
|
||||||
#define _TD_TSDB_COMMIT_QUEUE_H_
|
#define _TD_TSDB_COMMIT_QUEUE_H_
|
||||||
|
|
||||||
int tsdbScheduleCommit(STsdbRepo *pRepo);
|
typedef enum { COMMIT_REQ, COMPACT_REQ } TSDB_REQ_T;
|
||||||
|
|
||||||
|
int tsdbScheduleCommit(STsdbRepo *pRepo, TSDB_REQ_T req);
|
||||||
|
|
||||||
#endif /* _TD_TSDB_COMMIT_QUEUE_H_ */
|
#endif /* _TD_TSDB_COMMIT_QUEUE_H_ */
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can use, redistribute, and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3
|
||||||
|
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef _TD_TSDB_COMPACT_H_
|
||||||
|
#define _TD_TSDB_COMPACT_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void *tsdbCompactImpl(STsdbRepo *pRepo);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TD_TSDB_COMPACT_H_ */
|
|
@ -64,6 +64,8 @@ extern "C" {
|
||||||
#include "tsdbReadImpl.h"
|
#include "tsdbReadImpl.h"
|
||||||
// Commit
|
// Commit
|
||||||
#include "tsdbCommit.h"
|
#include "tsdbCommit.h"
|
||||||
|
// Compact
|
||||||
|
#include "tsdbCompact.h"
|
||||||
// Commit Queue
|
// Commit Queue
|
||||||
#include "tsdbCommitQueue.h"
|
#include "tsdbCommitQueue.h"
|
||||||
// Main definitions
|
// Main definitions
|
||||||
|
|
|
@ -51,7 +51,7 @@ typedef struct {
|
||||||
#define TSDB_COMMIT_LAST_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_LAST)
|
#define TSDB_COMMIT_LAST_FILE(ch) TSDB_DFILE_IN_SET(TSDB_COMMIT_WRITE_FSET(ch), TSDB_FILE_LAST)
|
||||||
#define TSDB_COMMIT_BUF(ch) TSDB_READ_BUF(&((ch)->readh))
|
#define TSDB_COMMIT_BUF(ch) TSDB_READ_BUF(&((ch)->readh))
|
||||||
#define TSDB_COMMIT_COMP_BUF(ch) TSDB_READ_COMP_BUF(&((ch)->readh))
|
#define TSDB_COMMIT_COMP_BUF(ch) TSDB_READ_COMP_BUF(&((ch)->readh))
|
||||||
#define TSDB_COMMIT_DEFAULT_ROWS(ch) (TSDB_COMMIT_REPO(ch)->config.maxRowsPerFileBlock * 4 / 5)
|
#define TSDB_COMMIT_DEFAULT_ROWS(ch) TSDB_DEFAULT_BLOCK_ROWS(TSDB_COMMIT_REPO(ch)->config.maxRowsPerFileBlock)
|
||||||
#define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch)))
|
#define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch)))
|
||||||
|
|
||||||
static int tsdbCommitMeta(STsdbRepo *pRepo);
|
static int tsdbCommitMeta(STsdbRepo *pRepo);
|
||||||
|
@ -72,7 +72,6 @@ static int tsdbCommitToTable(SCommitH *pCommith, int tid);
|
||||||
static int tsdbSetCommitTable(SCommitH *pCommith, STable *pTable);
|
static int tsdbSetCommitTable(SCommitH *pCommith, STable *pTable);
|
||||||
static int tsdbComparKeyBlock(const void *arg1, const void *arg2);
|
static int tsdbComparKeyBlock(const void *arg1, const void *arg2);
|
||||||
static int tsdbWriteBlockInfo(SCommitH *pCommih);
|
static int tsdbWriteBlockInfo(SCommitH *pCommih);
|
||||||
static int tsdbWriteBlockIdx(SCommitH *pCommih);
|
|
||||||
static int tsdbCommitMemData(SCommitH *pCommith, SCommitIter *pIter, TSKEY keyLimit, bool toData);
|
static int tsdbCommitMemData(SCommitH *pCommith, SCommitIter *pIter, TSKEY keyLimit, bool toData);
|
||||||
static int tsdbMergeMemData(SCommitH *pCommith, SCommitIter *pIter, int bidx);
|
static int tsdbMergeMemData(SCommitH *pCommith, SCommitIter *pIter, int bidx);
|
||||||
static int tsdbMoveBlock(SCommitH *pCommith, int bidx);
|
static int tsdbMoveBlock(SCommitH *pCommith, int bidx);
|
||||||
|
@ -86,7 +85,6 @@ static void tsdbCloseCommitFile(SCommitH *pCommith, bool hasError);
|
||||||
static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *pInfo);
|
static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *pInfo);
|
||||||
static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIter *pCommitIter, SDataCols *pTarget,
|
static void tsdbLoadAndMergeFromCache(SDataCols *pDataCols, int *iter, SCommitIter *pCommitIter, SDataCols *pTarget,
|
||||||
TSKEY maxKey, int maxRows, int8_t update);
|
TSKEY maxKey, int maxRows, int8_t update);
|
||||||
static int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn);
|
|
||||||
|
|
||||||
void *tsdbCommitData(STsdbRepo *pRepo) {
|
void *tsdbCommitData(STsdbRepo *pRepo) {
|
||||||
if (pRepo->imem == NULL) {
|
if (pRepo->imem == NULL) {
|
||||||
|
@ -117,6 +115,151 @@ _err:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn) {
|
||||||
|
SDiskID did;
|
||||||
|
SDFileSet nSet;
|
||||||
|
STsdbFS * pfs = REPO_FS(pRepo);
|
||||||
|
int level;
|
||||||
|
|
||||||
|
ASSERT(pSet->fid >= pRtn->minFid);
|
||||||
|
|
||||||
|
level = tsdbGetFidLevel(pSet->fid, pRtn);
|
||||||
|
|
||||||
|
tfsAllocDisk(level, &(did.level), &(did.id));
|
||||||
|
if (did.level == TFS_UNDECIDED_LEVEL) {
|
||||||
|
terrno = TSDB_CODE_TDB_NO_AVAIL_DISK;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (did.level > TSDB_FSET_LEVEL(pSet)) {
|
||||||
|
// Need to move the FSET to higher level
|
||||||
|
tsdbInitDFileSet(&nSet, did, REPO_ID(pRepo), pSet->fid, FS_TXN_VERSION(pfs));
|
||||||
|
|
||||||
|
if (tsdbCopyDFileSet(pSet, &nSet) < 0) {
|
||||||
|
tsdbError("vgId:%d failed to copy FSET %d from level %d to level %d since %s", REPO_ID(pRepo), pSet->fid,
|
||||||
|
TSDB_FSET_LEVEL(pSet), did.level, tstrerror(terrno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tsdbUpdateDFileSet(pfs, &nSet) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsdbInfo("vgId:%d FSET %d is copied from level %d disk id %d to level %d disk id %d", REPO_ID(pRepo), pSet->fid,
|
||||||
|
TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet), did.level, did.id);
|
||||||
|
} else {
|
||||||
|
// On a correct level
|
||||||
|
if (tsdbUpdateDFileSet(pfs, pSet) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tsdbWriteBlockInfoImpl(SDFile *pHeadf, STable *pTable, SArray *pSupA, SArray *pSubA, void **ppBuf,
|
||||||
|
SBlockIdx *pIdx) {
|
||||||
|
size_t nSupBlocks;
|
||||||
|
size_t nSubBlocks;
|
||||||
|
uint32_t tlen;
|
||||||
|
SBlockInfo *pBlkInfo;
|
||||||
|
int64_t offset;
|
||||||
|
SBlock * pBlock;
|
||||||
|
|
||||||
|
memset(pIdx, 0, sizeof(*pIdx));
|
||||||
|
|
||||||
|
nSupBlocks = taosArrayGetSize(pSupA);
|
||||||
|
nSubBlocks = (pSubA == NULL) ? 0 : taosArrayGetSize(pSubA);
|
||||||
|
|
||||||
|
if (nSupBlocks <= 0) {
|
||||||
|
// No data (data all deleted)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tlen = (uint32_t)(sizeof(SBlockInfo) + sizeof(SBlock) * (nSupBlocks + nSubBlocks) + sizeof(TSCKSUM));
|
||||||
|
if (tsdbMakeRoom(ppBuf, tlen) < 0) return -1;
|
||||||
|
pBlkInfo = *ppBuf;
|
||||||
|
|
||||||
|
pBlkInfo->delimiter = TSDB_FILE_DELIMITER;
|
||||||
|
pBlkInfo->tid = TABLE_TID(pTable);
|
||||||
|
pBlkInfo->uid = TABLE_UID(pTable);
|
||||||
|
|
||||||
|
memcpy((void *)(pBlkInfo->blocks), taosArrayGet(pSupA, 0), nSupBlocks * sizeof(SBlock));
|
||||||
|
if (nSubBlocks > 0) {
|
||||||
|
memcpy((void *)(pBlkInfo->blocks + nSupBlocks), taosArrayGet(pSubA, 0), nSubBlocks * sizeof(SBlock));
|
||||||
|
|
||||||
|
for (int i = 0; i < nSupBlocks; i++) {
|
||||||
|
pBlock = pBlkInfo->blocks + i;
|
||||||
|
|
||||||
|
if (pBlock->numOfSubBlocks > 1) {
|
||||||
|
pBlock->offset += (sizeof(SBlockInfo) + sizeof(SBlock) * nSupBlocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taosCalcChecksumAppend(0, (uint8_t *)pBlkInfo, tlen);
|
||||||
|
|
||||||
|
if (tsdbAppendDFile(pHeadf, (void *)pBlkInfo, tlen, &offset) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(pBlkInfo, tlen - sizeof(TSCKSUM)));
|
||||||
|
|
||||||
|
// Set pIdx
|
||||||
|
pBlock = taosArrayGetLast(pSupA);
|
||||||
|
|
||||||
|
pIdx->tid = TABLE_TID(pTable);
|
||||||
|
pIdx->uid = TABLE_UID(pTable);
|
||||||
|
pIdx->hasLast = pBlock->last ? 1 : 0;
|
||||||
|
pIdx->maxKey = pBlock->keyLast;
|
||||||
|
pIdx->numOfBlocks = (uint32_t)nSupBlocks;
|
||||||
|
pIdx->len = tlen;
|
||||||
|
pIdx->offset = (uint32_t)offset;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf) {
|
||||||
|
SBlockIdx *pBlkIdx;
|
||||||
|
size_t nidx = taosArrayGetSize(pIdxA);
|
||||||
|
int tlen = 0, size;
|
||||||
|
int64_t offset;
|
||||||
|
|
||||||
|
if (nidx <= 0) {
|
||||||
|
// All data are deleted
|
||||||
|
pHeadf->info.offset = 0;
|
||||||
|
pHeadf->info.len = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < nidx; i++) {
|
||||||
|
pBlkIdx = (SBlockIdx *)taosArrayGet(pIdxA, i);
|
||||||
|
|
||||||
|
size = tsdbEncodeSBlockIdx(NULL, pBlkIdx);
|
||||||
|
if (tsdbMakeRoom(ppBuf, tlen + size) < 0) return -1;
|
||||||
|
|
||||||
|
void *ptr = POINTER_SHIFT(*ppBuf, tlen);
|
||||||
|
tsdbEncodeSBlockIdx(&ptr, pBlkIdx);
|
||||||
|
|
||||||
|
tlen += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
tlen += sizeof(TSCKSUM);
|
||||||
|
if (tsdbMakeRoom(ppBuf, tlen) < 0) return -1;
|
||||||
|
taosCalcChecksumAppend(0, (uint8_t *)(*ppBuf), tlen);
|
||||||
|
|
||||||
|
if (tsdbAppendDFile(pHeadf, *ppBuf, tlen, &offset) < tlen) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(*ppBuf, tlen - sizeof(TSCKSUM)));
|
||||||
|
pHeadf->info.offset = (uint32_t)offset;
|
||||||
|
pHeadf->info.len = tlen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =================== Commit Meta Data
|
// =================== Commit Meta Data
|
||||||
static int tsdbCommitMeta(STsdbRepo *pRepo) {
|
static int tsdbCommitMeta(STsdbRepo *pRepo) {
|
||||||
STsdbFS * pfs = REPO_FS(pRepo);
|
STsdbFS * pfs = REPO_FS(pRepo);
|
||||||
|
@ -446,7 +589,8 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsdbWriteBlockIdx(pCommith) < 0) {
|
if (tsdbWriteBlockIdx(TSDB_COMMIT_HEAD_FILE(pCommith), pCommith->aBlkIdx, (void **)(&(TSDB_COMMIT_BUF(pCommith)))) <
|
||||||
|
0) {
|
||||||
tsdbError("vgId:%d failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), fid, tstrerror(terrno));
|
tsdbError("vgId:%d failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), fid, tstrerror(terrno));
|
||||||
tsdbCloseCommitFile(pCommith, true);
|
tsdbCloseCommitFile(pCommith, true);
|
||||||
// revert the file change
|
// revert the file change
|
||||||
|
@ -754,23 +898,21 @@ static int tsdbComparKeyBlock(const void *arg1, const void *arg2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast,
|
int tsdbWriteBlockImpl(STsdbRepo *pRepo, STable *pTable, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock,
|
||||||
bool isSuper) {
|
bool isLast, bool isSuper, void **ppBuf, void **ppCBuf) {
|
||||||
STsdbRepo * pRepo = TSDB_COMMIT_REPO(pCommith);
|
|
||||||
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
||||||
SBlockData *pBlockData;
|
SBlockData *pBlockData;
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
STable * pTable = TSDB_COMMIT_TABLE(pCommith);
|
|
||||||
int rowsToWrite = pDataCols->numOfRows;
|
int rowsToWrite = pDataCols->numOfRows;
|
||||||
|
|
||||||
ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock);
|
ASSERT(rowsToWrite > 0 && rowsToWrite <= pCfg->maxRowsPerFileBlock);
|
||||||
ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock);
|
ASSERT((!isLast) || rowsToWrite < pCfg->minRowsPerFileBlock);
|
||||||
|
|
||||||
// Make buffer space
|
// Make buffer space
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_COMMIT_BUF(pCommith)), TSDB_BLOCK_STATIS_SIZE(pDataCols->numOfCols)) < 0) {
|
if (tsdbMakeRoom(ppBuf, TSDB_BLOCK_STATIS_SIZE(pDataCols->numOfCols)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pBlockData = (SBlockData *)TSDB_COMMIT_BUF(pCommith);
|
pBlockData = (SBlockData *)(*ppBuf);
|
||||||
|
|
||||||
// Get # of cols not all NULL(not including key column)
|
// Get # of cols not all NULL(not including key column)
|
||||||
int nColsNotAllNull = 0;
|
int nColsNotAllNull = 0;
|
||||||
|
@ -816,23 +958,23 @@ static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCo
|
||||||
void * tptr;
|
void * tptr;
|
||||||
|
|
||||||
// Make room
|
// Make room
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_COMMIT_BUF(pCommith)), lsize + tlen + COMP_OVERFLOW_BYTES + sizeof(TSCKSUM)) < 0) {
|
if (tsdbMakeRoom(ppBuf, lsize + tlen + COMP_OVERFLOW_BYTES + sizeof(TSCKSUM)) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pBlockData = (SBlockData *)TSDB_COMMIT_BUF(pCommith);
|
pBlockData = (SBlockData *)(*ppBuf);
|
||||||
pBlockCol = pBlockData->cols + tcol;
|
pBlockCol = pBlockData->cols + tcol;
|
||||||
tptr = POINTER_SHIFT(pBlockData, lsize);
|
tptr = POINTER_SHIFT(pBlockData, lsize);
|
||||||
|
|
||||||
if (pCfg->compression == TWO_STAGE_COMP &&
|
if (pCfg->compression == TWO_STAGE_COMP &&
|
||||||
tsdbMakeRoom((void **)(&TSDB_COMMIT_COMP_BUF(pCommith)), tlen + COMP_OVERFLOW_BYTES) < 0) {
|
tsdbMakeRoom(ppCBuf, tlen + COMP_OVERFLOW_BYTES) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress or just copy
|
// Compress or just copy
|
||||||
if (pCfg->compression) {
|
if (pCfg->compression) {
|
||||||
flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite, tptr,
|
flen = (*(tDataTypes[pDataCol->type].compFunc))((char *)pDataCol->pData, tlen, rowsToWrite, tptr,
|
||||||
tlen + COMP_OVERFLOW_BYTES, pCfg->compression,
|
tlen + COMP_OVERFLOW_BYTES, pCfg->compression, *ppCBuf,
|
||||||
TSDB_COMMIT_COMP_BUF(pCommith), tlen + COMP_OVERFLOW_BYTES);
|
tlen + COMP_OVERFLOW_BYTES);
|
||||||
} else {
|
} else {
|
||||||
flen = tlen;
|
flen = tlen;
|
||||||
memcpy(tptr, pDataCol->pData, flen);
|
memcpy(tptr, pDataCol->pData, flen);
|
||||||
|
@ -888,68 +1030,27 @@ static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCo
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tsdbWriteBlock(SCommitH *pCommith, SDFile *pDFile, SDataCols *pDataCols, SBlock *pBlock, bool isLast,
|
||||||
|
bool isSuper) {
|
||||||
|
return tsdbWriteBlockImpl(TSDB_COMMIT_REPO(pCommith), TSDB_COMMIT_TABLE(pCommith), pDFile, pDataCols, pBlock, isLast,
|
||||||
|
isSuper, (void **)(&(TSDB_COMMIT_BUF(pCommith))),
|
||||||
|
(void **)(&(TSDB_COMMIT_COMP_BUF(pCommith))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int tsdbWriteBlockInfo(SCommitH *pCommih) {
|
static int tsdbWriteBlockInfo(SCommitH *pCommih) {
|
||||||
SDFile * pHeadf = TSDB_COMMIT_HEAD_FILE(pCommih);
|
SDFile * pHeadf = TSDB_COMMIT_HEAD_FILE(pCommih);
|
||||||
SBlockIdx blkIdx;
|
SBlockIdx blkIdx;
|
||||||
STable * pTable = TSDB_COMMIT_TABLE(pCommih);
|
STable * pTable = TSDB_COMMIT_TABLE(pCommih);
|
||||||
SBlock * pBlock;
|
|
||||||
size_t nSupBlocks;
|
|
||||||
size_t nSubBlocks;
|
|
||||||
uint32_t tlen;
|
|
||||||
SBlockInfo *pBlkInfo;
|
|
||||||
int64_t offset;
|
|
||||||
|
|
||||||
nSupBlocks = taosArrayGetSize(pCommih->aSupBlk);
|
if (tsdbWriteBlockInfoImpl(pHeadf, pTable, pCommih->aSupBlk, pCommih->aSubBlk, (void **)(&(TSDB_COMMIT_BUF(pCommih))),
|
||||||
nSubBlocks = taosArrayGetSize(pCommih->aSubBlk);
|
&blkIdx) < 0) {
|
||||||
|
|
||||||
if (nSupBlocks <= 0) {
|
|
||||||
// No data (data all deleted)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
tlen = (uint32_t)(sizeof(SBlockInfo) + sizeof(SBlock) * (nSupBlocks + nSubBlocks) + sizeof(TSCKSUM));
|
|
||||||
|
|
||||||
// Write SBlockInfo part
|
|
||||||
if (tsdbMakeRoom((void **)(&(TSDB_COMMIT_BUF(pCommih))), tlen) < 0) return -1;
|
|
||||||
pBlkInfo = TSDB_COMMIT_BUF(pCommih);
|
|
||||||
|
|
||||||
pBlkInfo->delimiter = TSDB_FILE_DELIMITER;
|
|
||||||
pBlkInfo->tid = TABLE_TID(pTable);
|
|
||||||
pBlkInfo->uid = TABLE_UID(pTable);
|
|
||||||
|
|
||||||
memcpy((void *)(pBlkInfo->blocks), taosArrayGet(pCommih->aSupBlk, 0), nSupBlocks * sizeof(SBlock));
|
|
||||||
if (nSubBlocks > 0) {
|
|
||||||
memcpy((void *)(pBlkInfo->blocks + nSupBlocks), taosArrayGet(pCommih->aSubBlk, 0), nSubBlocks * sizeof(SBlock));
|
|
||||||
|
|
||||||
for (int i = 0; i < nSupBlocks; i++) {
|
|
||||||
pBlock = pBlkInfo->blocks + i;
|
|
||||||
|
|
||||||
if (pBlock->numOfSubBlocks > 1) {
|
|
||||||
pBlock->offset += (sizeof(SBlockInfo) + sizeof(SBlock) * nSupBlocks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
taosCalcChecksumAppend(0, (uint8_t *)pBlkInfo, tlen);
|
|
||||||
|
|
||||||
if (tsdbAppendDFile(pHeadf, TSDB_COMMIT_BUF(pCommih), tlen, &offset) < 0) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(pBlkInfo, tlen - sizeof(TSCKSUM)));
|
if (blkIdx.numOfBlocks == 0) {
|
||||||
|
return 0;
|
||||||
// Set blkIdx
|
}
|
||||||
pBlock = taosArrayGet(pCommih->aSupBlk, nSupBlocks - 1);
|
|
||||||
|
|
||||||
blkIdx.tid = TABLE_TID(pTable);
|
|
||||||
blkIdx.uid = TABLE_UID(pTable);
|
|
||||||
blkIdx.hasLast = pBlock->last ? 1 : 0;
|
|
||||||
blkIdx.maxKey = pBlock->keyLast;
|
|
||||||
blkIdx.numOfBlocks = (uint32_t)nSupBlocks;
|
|
||||||
blkIdx.len = tlen;
|
|
||||||
blkIdx.offset = (uint32_t)offset;
|
|
||||||
|
|
||||||
ASSERT(blkIdx.numOfBlocks > 0);
|
|
||||||
|
|
||||||
if (taosArrayPush(pCommih->aBlkIdx, (void *)(&blkIdx)) == NULL) {
|
if (taosArrayPush(pCommih->aBlkIdx, (void *)(&blkIdx)) == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
|
@ -959,49 +1060,6 @@ static int tsdbWriteBlockInfo(SCommitH *pCommih) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbWriteBlockIdx(SCommitH *pCommih) {
|
|
||||||
SBlockIdx *pBlkIdx = NULL;
|
|
||||||
SDFile * pHeadf = TSDB_COMMIT_HEAD_FILE(pCommih);
|
|
||||||
size_t nidx = taosArrayGetSize(pCommih->aBlkIdx);
|
|
||||||
int tlen = 0, size = 0;
|
|
||||||
int64_t offset = 0;
|
|
||||||
|
|
||||||
if (nidx <= 0) {
|
|
||||||
// All data are deleted
|
|
||||||
pHeadf->info.offset = 0;
|
|
||||||
pHeadf->info.len = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < nidx; i++) {
|
|
||||||
pBlkIdx = (SBlockIdx *)taosArrayGet(pCommih->aBlkIdx, i);
|
|
||||||
|
|
||||||
size = tsdbEncodeSBlockIdx(NULL, pBlkIdx);
|
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_COMMIT_BUF(pCommih)), tlen + size) < 0) return -1;
|
|
||||||
|
|
||||||
void *ptr = POINTER_SHIFT(TSDB_COMMIT_BUF(pCommih), tlen);
|
|
||||||
tsdbEncodeSBlockIdx(&ptr, pBlkIdx);
|
|
||||||
|
|
||||||
tlen += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
tlen += sizeof(TSCKSUM);
|
|
||||||
if (tsdbMakeRoom((void **)(&TSDB_COMMIT_BUF(pCommih)), tlen) < 0) return -1;
|
|
||||||
taosCalcChecksumAppend(0, (uint8_t *)TSDB_COMMIT_BUF(pCommih), tlen);
|
|
||||||
|
|
||||||
if (tsdbAppendDFile(pHeadf, TSDB_COMMIT_BUF(pCommih), tlen, &offset) < tlen) {
|
|
||||||
tsdbError("vgId:%d failed to write block index part to file %s since %s", TSDB_COMMIT_REPO_ID(pCommih),
|
|
||||||
TSDB_FILE_FULL_NAME(pHeadf), tstrerror(terrno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsdbUpdateDFileMagic(pHeadf, POINTER_SHIFT(TSDB_COMMIT_BUF(pCommih), tlen - sizeof(TSCKSUM)));
|
|
||||||
pHeadf->info.offset = (uint32_t)offset;
|
|
||||||
pHeadf->info.len = tlen;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tsdbCommitMemData(SCommitH *pCommith, SCommitIter *pIter, TSKEY keyLimit, bool toData) {
|
static int tsdbCommitMemData(SCommitH *pCommith, SCommitIter *pIter, TSKEY keyLimit, bool toData) {
|
||||||
STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith);
|
STsdbRepo *pRepo = TSDB_COMMIT_REPO(pCommith);
|
||||||
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
STsdbCfg * pCfg = REPO_CFG(pRepo);
|
||||||
|
@ -1454,45 +1512,3 @@ int tsdbApplyRtn(STsdbRepo *pRepo) {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsdbApplyRtnOnFSet(STsdbRepo *pRepo, SDFileSet *pSet, SRtn *pRtn) {
|
|
||||||
SDiskID did;
|
|
||||||
SDFileSet nSet;
|
|
||||||
STsdbFS * pfs = REPO_FS(pRepo);
|
|
||||||
int level;
|
|
||||||
|
|
||||||
ASSERT(pSet->fid >= pRtn->minFid);
|
|
||||||
|
|
||||||
level = tsdbGetFidLevel(pSet->fid, pRtn);
|
|
||||||
|
|
||||||
tfsAllocDisk(level, &(did.level), &(did.id));
|
|
||||||
if (did.level == TFS_UNDECIDED_LEVEL) {
|
|
||||||
terrno = TSDB_CODE_TDB_NO_AVAIL_DISK;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (did.level > TSDB_FSET_LEVEL(pSet)) {
|
|
||||||
// Need to move the FSET to higher level
|
|
||||||
tsdbInitDFileSet(&nSet, did, REPO_ID(pRepo), pSet->fid, FS_TXN_VERSION(pfs));
|
|
||||||
|
|
||||||
if (tsdbCopyDFileSet(pSet, &nSet) < 0) {
|
|
||||||
tsdbError("vgId:%d failed to copy FSET %d from level %d to level %d since %s", REPO_ID(pRepo), pSet->fid,
|
|
||||||
TSDB_FSET_LEVEL(pSet), did.level, tstrerror(terrno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tsdbUpdateDFileSet(pfs, &nSet) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tsdbInfo("vgId:%d FSET %d is copied from level %d disk id %d to level %d disk id %d", REPO_ID(pRepo), pSet->fid,
|
|
||||||
TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet), did.level, did.id);
|
|
||||||
} else {
|
|
||||||
// On a correct level
|
|
||||||
if (tsdbUpdateDFileSet(pfs, pSet) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -26,8 +26,9 @@ typedef struct {
|
||||||
} SCommitQueue;
|
} SCommitQueue;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
TSDB_REQ_T req;
|
||||||
STsdbRepo *pRepo;
|
STsdbRepo *pRepo;
|
||||||
} SCommitReq;
|
} SReq;
|
||||||
|
|
||||||
static void *tsdbLoopCommit(void *arg);
|
static void *tsdbLoopCommit(void *arg);
|
||||||
|
|
||||||
|
@ -90,16 +91,17 @@ void tsdbDestroyCommitQueue() {
|
||||||
pthread_mutex_destroy(&(pQueue->lock));
|
pthread_mutex_destroy(&(pQueue->lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
int tsdbScheduleCommit(STsdbRepo *pRepo) {
|
int tsdbScheduleCommit(STsdbRepo *pRepo, TSDB_REQ_T req) {
|
||||||
SCommitQueue *pQueue = &tsCommitQueue;
|
SCommitQueue *pQueue = &tsCommitQueue;
|
||||||
|
|
||||||
SListNode *pNode = (SListNode *)calloc(1, sizeof(SListNode) + sizeof(SCommitReq));
|
SListNode *pNode = (SListNode *)calloc(1, sizeof(SListNode) + sizeof(SReq));
|
||||||
if (pNode == NULL) {
|
if (pNode == NULL) {
|
||||||
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
((SCommitReq *)pNode->data)->pRepo = pRepo;
|
((SReq *)pNode->data)->req = req;
|
||||||
|
((SReq *)pNode->data)->pRepo = pRepo;
|
||||||
|
|
||||||
pthread_mutex_lock(&(pQueue->lock));
|
pthread_mutex_lock(&(pQueue->lock));
|
||||||
|
|
||||||
|
@ -154,6 +156,7 @@ static void *tsdbLoopCommit(void *arg) {
|
||||||
SCommitQueue *pQueue = &tsCommitQueue;
|
SCommitQueue *pQueue = &tsCommitQueue;
|
||||||
SListNode * pNode = NULL;
|
SListNode * pNode = NULL;
|
||||||
STsdbRepo * pRepo = NULL;
|
STsdbRepo * pRepo = NULL;
|
||||||
|
TSDB_REQ_T req;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
pthread_mutex_lock(&(pQueue->lock));
|
pthread_mutex_lock(&(pQueue->lock));
|
||||||
|
@ -174,14 +177,22 @@ static void *tsdbLoopCommit(void *arg) {
|
||||||
|
|
||||||
pthread_mutex_unlock(&(pQueue->lock));
|
pthread_mutex_unlock(&(pQueue->lock));
|
||||||
|
|
||||||
pRepo = ((SCommitReq *)pNode->data)->pRepo;
|
req = ((SReq *)pNode->data)->req;
|
||||||
|
pRepo = ((SReq *)pNode->data)->pRepo;
|
||||||
|
|
||||||
// check if need to apply new config
|
// check if need to apply new config
|
||||||
if (pRepo->config_changed) {
|
if (pRepo->config_changed) {
|
||||||
tsdbApplyRepoConfig(pRepo);
|
tsdbApplyRepoConfig(pRepo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req == COMMIT_REQ) {
|
||||||
tsdbCommitData(pRepo);
|
tsdbCommitData(pRepo);
|
||||||
|
} else if (req == COMPACT_REQ) {
|
||||||
|
tsdbCompactImpl(pRepo);
|
||||||
|
} else {
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
listNodeFree(pNode);
|
listNodeFree(pNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,11 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "tsdb.h"
|
||||||
|
|
||||||
|
#ifndef _TSDB_PLUGINS
|
||||||
|
|
||||||
|
int tsdbCompact(STsdbRepo *pRepo) { return 0; }
|
||||||
|
void *tsdbCompactImpl(STsdbRepo *pRepo) { return NULL; }
|
||||||
|
|
||||||
|
#endif
|
|
@ -288,7 +288,7 @@ int tsdbAsyncCommit(STsdbRepo *pRepo) {
|
||||||
if (tsdbLockRepo(pRepo) < 0) return -1;
|
if (tsdbLockRepo(pRepo) < 0) return -1;
|
||||||
pRepo->imem = pRepo->mem;
|
pRepo->imem = pRepo->mem;
|
||||||
pRepo->mem = NULL;
|
pRepo->mem = NULL;
|
||||||
tsdbScheduleCommit(pRepo);
|
tsdbScheduleCommit(pRepo, COMMIT_REQ);
|
||||||
if (tsdbUnlockRepo(pRepo) < 0) return -1;
|
if (tsdbUnlockRepo(pRepo) < 0) return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -68,7 +68,7 @@ int tsdbCreateTable(STsdbRepo *repo, STableCfg *pCfg) {
|
||||||
TABLE_CHAR_NAME(pMeta->tables[tid]), TABLE_TID(pMeta->tables[tid]), TABLE_UID(pMeta->tables[tid]));
|
TABLE_CHAR_NAME(pMeta->tables[tid]), TABLE_TID(pMeta->tables[tid]), TABLE_UID(pMeta->tables[tid]));
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
tsdbError("vgId:%d table %s at tid %d uid %" PRIu64
|
tsdbInfo("vgId:%d table %s at tid %d uid %" PRIu64
|
||||||
" exists, replace it with new table, this can be not reasonable",
|
" exists, replace it with new table, this can be not reasonable",
|
||||||
REPO_ID(pRepo), TABLE_CHAR_NAME(pMeta->tables[tid]), TABLE_TID(pMeta->tables[tid]),
|
REPO_ID(pRepo), TABLE_CHAR_NAME(pMeta->tables[tid]), TABLE_TID(pMeta->tables[tid]),
|
||||||
TABLE_UID(pMeta->tables[tid]));
|
TABLE_UID(pMeta->tables[tid]));
|
||||||
|
@ -1055,10 +1055,7 @@ static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable) {
|
||||||
STable *pSTable = pTable->pSuper;
|
STable *pSTable = pTable->pSuper;
|
||||||
ASSERT(pSTable != NULL);
|
ASSERT(pSTable != NULL);
|
||||||
|
|
||||||
STSchema *pSchema = tsdbGetTableTagSchema(pTable);
|
char* key = getTagIndexKey(pTable);
|
||||||
STColumn *pCol = schemaColAt(pSchema, DEFAULT_TAG_INDEX_COLUMN);
|
|
||||||
|
|
||||||
char * key = tdGetKVRowValOfCol(pTable->tagVal, pCol->colId);
|
|
||||||
SArray *res = tSkipListGet(pSTable->pIndex, key);
|
SArray *res = tSkipListGet(pSTable->pIndex, key);
|
||||||
|
|
||||||
size_t size = taosArrayGetSize(res);
|
size_t size = taosArrayGetSize(res);
|
||||||
|
|
|
@ -368,20 +368,21 @@ static STsdbQueryHandle* tsdbQueryTablesImpl(STsdbRepo* tsdb, STsdbQueryCond* pC
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pCond != NULL && pCond->numOfCols > 0 && pMemRef != NULL);
|
assert(pCond != NULL && pMemRef != NULL);
|
||||||
if (ASCENDING_TRAVERSE(pCond->order)) {
|
if (ASCENDING_TRAVERSE(pCond->order)) {
|
||||||
assert(pQueryHandle->window.skey <= pQueryHandle->window.ekey);
|
assert(pQueryHandle->window.skey <= pQueryHandle->window.ekey);
|
||||||
} else {
|
} else {
|
||||||
assert(pQueryHandle->window.skey >= pQueryHandle->window.ekey);
|
assert(pQueryHandle->window.skey >= pQueryHandle->window.ekey);
|
||||||
}
|
}
|
||||||
|
if (pCond->numOfCols > 0) {
|
||||||
// allocate buffer in order to load data blocks from file
|
// allocate buffer in order to load data blocks from file
|
||||||
pQueryHandle->statis = calloc(pCond->numOfCols, sizeof(SDataStatis));
|
pQueryHandle->statis = calloc(pCond->numOfCols, sizeof(SDataStatis));
|
||||||
if (pQueryHandle->statis == NULL) {
|
if (pQueryHandle->statis == NULL) {
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
pQueryHandle->pColumns = taosArrayInit(pCond->numOfCols, sizeof(SColumnInfoData)); // todo: use list instead of array?
|
pQueryHandle->pColumns =
|
||||||
|
taosArrayInit(pCond->numOfCols, sizeof(SColumnInfoData)); // todo: use list instead of array?
|
||||||
if (pQueryHandle->pColumns == NULL) {
|
if (pQueryHandle->pColumns == NULL) {
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
}
|
}
|
||||||
|
@ -398,10 +399,8 @@ static STsdbQueryHandle* tsdbQueryTablesImpl(STsdbRepo* tsdb, STsdbQueryCond* pC
|
||||||
pQueryHandle->statis[i].colId = colInfo.info.colId;
|
pQueryHandle->statis[i].colId = colInfo.info.colId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCond->numOfCols > 0) {
|
|
||||||
pQueryHandle->defaultLoadColumn = getDefaultLoadColumns(pQueryHandle, true);
|
pQueryHandle->defaultLoadColumn = getDefaultLoadColumns(pQueryHandle, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
STsdbMeta* pMeta = tsdbGetMeta(tsdb);
|
STsdbMeta* pMeta = tsdbGetMeta(tsdb);
|
||||||
assert(pMeta != NULL);
|
assert(pMeta != NULL);
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ int tsdbLoadBlockData(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo) {
|
||||||
for (int i = 1; i < pBlock->numOfSubBlocks; i++) {
|
for (int i = 1; i < pBlock->numOfSubBlocks; i++) {
|
||||||
iBlock++;
|
iBlock++;
|
||||||
if (tsdbLoadBlockDataImpl(pReadh, iBlock, pReadh->pDCols[1]) < 0) return -1;
|
if (tsdbLoadBlockDataImpl(pReadh, iBlock, pReadh->pDCols[1]) < 0) return -1;
|
||||||
if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows) < 0) return -1;
|
if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(pReadh->pDCols[0]->numOfRows == pBlock->numOfRows);
|
ASSERT(pReadh->pDCols[0]->numOfRows == pBlock->numOfRows);
|
||||||
|
@ -284,7 +284,7 @@ int tsdbLoadBlockDataCols(SReadH *pReadh, SBlock *pBlock, SBlockInfo *pBlkInfo,
|
||||||
for (int i = 1; i < pBlock->numOfSubBlocks; i++) {
|
for (int i = 1; i < pBlock->numOfSubBlocks; i++) {
|
||||||
iBlock++;
|
iBlock++;
|
||||||
if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[1], colIds, numOfColsIds) < 0) return -1;
|
if (tsdbLoadBlockDataColsImpl(pReadh, iBlock, pReadh->pDCols[1], colIds, numOfColsIds) < 0) return -1;
|
||||||
if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows) < 0) return -1;
|
if (tdMergeDataCols(pReadh->pDCols[0], pReadh->pDCols[1], pReadh->pDCols[1]->numOfRows, NULL) < 0) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(pReadh->pDCols[0]->numOfRows == pBlock->numOfRows);
|
ASSERT(pReadh->pDCols[0]->numOfRows == pBlock->numOfRows);
|
||||||
|
|
|
@ -183,6 +183,7 @@ void taosCleanupKeywordsTable();
|
||||||
|
|
||||||
SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken);
|
SStrToken tscReplaceStrToken(char **str, SStrToken *token, const char* newToken);
|
||||||
|
|
||||||
|
SStrToken taosTokenDup(SStrToken* pToken, char* buf, int32_t len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,6 +224,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FULL, "Database memory is fu
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full for waiting commit")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FLOWCTRL, "Database memory is full for waiting commit")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_DROPPING, "Database is dropping")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_DROPPING, "Database is dropping")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_BALANCING, "Database is balancing")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_BALANCING, "Database is balancing")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_CLOSING, "Database is closing")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, "Database suspended")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, "Database suspended")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, "Database write operation denied")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, "Database write operation denied")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_SYNCING, "Database is syncing")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_SYNCING, "Database is syncing")
|
||||||
|
|
|
@ -141,6 +141,7 @@ static SKeyword keywordTable[] = {
|
||||||
{"VARIABLE", TK_VARIABLE},
|
{"VARIABLE", TK_VARIABLE},
|
||||||
{"INTERVAL", TK_INTERVAL},
|
{"INTERVAL", TK_INTERVAL},
|
||||||
{"SESSION", TK_SESSION},
|
{"SESSION", TK_SESSION},
|
||||||
|
{"STATE_WINDOW", TK_STATE_WINDOW},
|
||||||
{"FILL", TK_FILL},
|
{"FILL", TK_FILL},
|
||||||
{"SLIDING", TK_SLIDING},
|
{"SLIDING", TK_SLIDING},
|
||||||
{"ORDER", TK_ORDER},
|
{"ORDER", TK_ORDER},
|
||||||
|
@ -674,3 +675,15 @@ void taosCleanupKeywordsTable() {
|
||||||
taosHashCleanup(m);
|
taosHashCleanup(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SStrToken taosTokenDup(SStrToken* pToken, char* buf, int32_t len) {
|
||||||
|
assert(pToken != NULL && buf != NULL);
|
||||||
|
SStrToken token = *pToken;
|
||||||
|
token.z = buf;
|
||||||
|
|
||||||
|
assert(len > token.n);
|
||||||
|
strncpy(token.z, pToken->z, pToken->n);
|
||||||
|
token.z[token.n] = 0;
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
|
@ -91,18 +91,18 @@ static void vnodeIncRef(void *ptNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vnodeAcquire(int32_t vgId) {
|
void *vnodeAcquire(int32_t vgId) {
|
||||||
SVnodeObj **ppVnode = NULL;
|
SVnodeObj *pVnode = NULL;
|
||||||
if (tsVnodesHash != NULL) {
|
if (tsVnodesHash != NULL) {
|
||||||
ppVnode = taosHashGetClone(tsVnodesHash, &vgId, sizeof(int32_t), vnodeIncRef, NULL, sizeof(void *));
|
taosHashGetClone(tsVnodesHash, &vgId, sizeof(int32_t), vnodeIncRef, &pVnode, sizeof(void *));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ppVnode == NULL || *ppVnode == NULL) {
|
if (pVnode == NULL) {
|
||||||
terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
|
terrno = TSDB_CODE_VND_INVALID_VGROUP_ID;
|
||||||
vDebug("vgId:%d, not exist", vgId);
|
vDebug("vgId:%d, not exist", vgId);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *ppVnode;
|
return pVnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vnodeRelease(void *vparam) {
|
void vnodeRelease(void *vparam) {
|
||||||
|
|
|
@ -303,6 +303,17 @@ static int32_t vnodeWriteToWQueueImp(SVWriteMsg *pWrite) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rparam) {
|
int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rparam) {
|
||||||
|
SVnodeObj *pVnode = vparam;
|
||||||
|
if (qtype == TAOS_QTYPE_RPC) {
|
||||||
|
if (!vnodeInReadyStatus(pVnode)) {
|
||||||
|
return TSDB_CODE_APP_NOT_READY; // it may be in deleting or closing state
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pVnode->role != TAOS_SYNC_ROLE_MASTER) {
|
||||||
|
return TSDB_CODE_APP_NOT_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SVWriteMsg *pWrite = vnodeBuildVWriteMsg(vparam, wparam, qtype, rparam);
|
SVWriteMsg *pWrite = vnodeBuildVWriteMsg(vparam, wparam, qtype, rparam);
|
||||||
if (pWrite == NULL) {
|
if (pWrite == NULL) {
|
||||||
assert(terrno != 0);
|
assert(terrno != 0);
|
||||||
|
|
|
@ -29,8 +29,8 @@ pipeline {
|
||||||
agent none
|
agent none
|
||||||
environment{
|
environment{
|
||||||
|
|
||||||
WK = '/var/lib/jenkins/workspace/TDinternal'
|
WK = '/data/lib/jenkins/workspace/TDinternal'
|
||||||
WKC= '/var/lib/jenkins/workspace/TDinternal/community'
|
WKC= '/data/lib/jenkins/workspace/TDinternal/community'
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
|
|
@ -6,9 +6,9 @@ events {
|
||||||
}
|
}
|
||||||
|
|
||||||
http {
|
http {
|
||||||
lua_package_path '$prefix/lua/?.lua;$prefix/rest/?.lua;/blah/?.lua;;';
|
lua_package_path '$prefix/lua/?.lua;$prefix/rest/?.lua;$prefix/rest/?/init.lua;;';
|
||||||
lua_package_cpath "$prefix/so/?.so;;";
|
lua_package_cpath "$prefix/so/?.so;;";
|
||||||
lua_code_cache off;
|
lua_code_cache on;
|
||||||
server {
|
server {
|
||||||
listen 7000;
|
listen 7000;
|
||||||
server_name restapi;
|
server_name restapi;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
local config = {
|
||||||
|
host = "127.0.0.1",
|
||||||
|
port = 6030,
|
||||||
|
database = "",
|
||||||
|
user = "root",
|
||||||
|
password = "taosdata",
|
||||||
|
max_packet_size = 1024 * 1024 ,
|
||||||
|
connection_pool_size = 64
|
||||||
|
}
|
||||||
|
return config
|
|
@ -0,0 +1,72 @@
|
||||||
|
local _M = {}
|
||||||
|
local driver = require "luaconnector51"
|
||||||
|
local water_mark = 0
|
||||||
|
local occupied = 0
|
||||||
|
local connection_pool = {}
|
||||||
|
|
||||||
|
function _M.new(o,config)
|
||||||
|
o = o or {}
|
||||||
|
o.connection_pool = connection_pool
|
||||||
|
o.water_mark = water_mark
|
||||||
|
o.occupied = occupied
|
||||||
|
if #connection_pool == 0 then
|
||||||
|
|
||||||
|
for i = 1, config.connection_pool_size do
|
||||||
|
local res = driver.connect(config)
|
||||||
|
if res.code ~= 0 then
|
||||||
|
ngx.log(ngx.ERR, "connect--- failed:"..res.error)
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
local object = {obj = res.conn, state = 0}
|
||||||
|
table.insert(o.connection_pool,i, object)
|
||||||
|
ngx.log(ngx.INFO, "add connection, now pool size:"..#(o.connection_pool))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(o, { __index = _M })
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M:get_connection()
|
||||||
|
|
||||||
|
local connection_obj
|
||||||
|
|
||||||
|
for i = 1, #connection_pool do
|
||||||
|
connection_obj = connection_pool[i]
|
||||||
|
if connection_obj.state == 0 then
|
||||||
|
connection_obj.state = 1
|
||||||
|
occupied = occupied +1
|
||||||
|
if occupied > water_mark then
|
||||||
|
water_mark = occupied
|
||||||
|
end
|
||||||
|
return connection_obj["obj"]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ngx.log(ngx.ERR,"ALERT! NO FREE CONNECTION.")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M:get_water_mark()
|
||||||
|
|
||||||
|
return water_mark
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M:release_connection(conn)
|
||||||
|
|
||||||
|
local connection_obj
|
||||||
|
|
||||||
|
for i = 1, #connection_pool do
|
||||||
|
connection_obj = connection_pool[i]
|
||||||
|
|
||||||
|
if connection_obj["obj"] == conn then
|
||||||
|
connection_obj["state"] = 0
|
||||||
|
occupied = occupied -1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return _M
|
|
@ -1,26 +1,11 @@
|
||||||
local driver = require "luaconnector51"
|
local driver = require "luaconnector51"
|
||||||
local cjson = require "cjson"
|
local cjson = require "cjson"
|
||||||
|
local Pool = require "tdpool"
|
||||||
|
local config = require "config"
|
||||||
ngx.say("start time:"..os.time())
|
ngx.say("start time:"..os.time())
|
||||||
|
|
||||||
|
local pool = Pool.new(Pool,config)
|
||||||
local config = {
|
local conn = pool:get_connection()
|
||||||
host = "127.0.0.1",
|
|
||||||
port = 6030,
|
|
||||||
database = "",
|
|
||||||
user = "root",
|
|
||||||
password = "taosdata",
|
|
||||||
max_packet_size = 1024 * 1024
|
|
||||||
}
|
|
||||||
|
|
||||||
local conn
|
|
||||||
local res = driver.connect(config)
|
|
||||||
if res.code ~=0 then
|
|
||||||
ngx.say("connect--- failed: "..res.error)
|
|
||||||
return
|
|
||||||
else
|
|
||||||
conn = res.conn
|
|
||||||
ngx.say("connect--- pass.")
|
|
||||||
end
|
|
||||||
|
|
||||||
local res = driver.query(conn,"drop database if exists nginx")
|
local res = driver.query(conn,"drop database if exists nginx")
|
||||||
if res.code ~=0 then
|
if res.code ~=0 then
|
||||||
|
@ -51,7 +36,7 @@ else
|
||||||
ngx.say("create table--- pass.")
|
ngx.say("create table--- pass.")
|
||||||
end
|
end
|
||||||
|
|
||||||
res = driver.query(conn,"insert into m1 values ('2019-09-01 00:00:00.001',0,'robotspace'), ('2019-09-01 00:00:00.002',1,'Hilink'),('2019-09-01 00:00:00.003',2,'Harmony')")
|
res = driver.query(conn,"insert into m1 values ('2019-09-01 00:00:00.001', 0, 'robotspace'), ('2019-09-01 00:00:00.002',1,'Hilink'),('2019-09-01 00:00:00.003',2,'Harmony')")
|
||||||
if res.code ~=0 then
|
if res.code ~=0 then
|
||||||
ngx.say("insert records failed: "..res.error)
|
ngx.say("insert records failed: "..res.error)
|
||||||
return
|
return
|
||||||
|
@ -77,7 +62,29 @@ else
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
driver.close(conn)
|
|
||||||
ngx.say("end time:"..os.time())
|
|
||||||
--ngx.log(ngx.ERR,"in test file.")
|
|
||||||
|
|
||||||
|
local flag = false
|
||||||
|
function query_callback(res)
|
||||||
|
if res.code ~=0 then
|
||||||
|
ngx.say("async_query_callback--- failed:"..res.error)
|
||||||
|
else
|
||||||
|
if(res.affected == 3) then
|
||||||
|
ngx.say("async_query_callback, insert records--- pass")
|
||||||
|
else
|
||||||
|
ngx.say("async_query_callback, insert records---failed: expect 3 affected records, actually affected "..res.affected)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
flag = true
|
||||||
|
end
|
||||||
|
|
||||||
|
driver.query_a(conn,"insert into m1 values ('2019-09-01 00:00:00.001', 3, 'robotspace'),('2019-09-01 00:00:00.006', 4, 'Hilink'),('2019-09-01 00:00:00.007', 6, 'Harmony')", query_callback)
|
||||||
|
|
||||||
|
while not flag do
|
||||||
|
-- ngx.say("i am here once...")
|
||||||
|
ngx.sleep(0.001) -- time unit is second
|
||||||
|
end
|
||||||
|
|
||||||
|
ngx.say("pool water_mark:"..pool:get_water_mark())
|
||||||
|
|
||||||
|
pool:release_connection(conn)
|
||||||
|
ngx.say("end time:"..os.time())
|
||||||
|
|
Binary file not shown.
|
@ -1,2 +1,8 @@
|
||||||
gcc -std=c99 lua_connector.c -fPIC -shared -o luaconnector.so -Wall -ltaos
|
lua_header_installed=`apt-cache policy liblua5.3-dev|grep Installed|grep none > /dev/null; echo $?`
|
||||||
|
if [ "$lua_header_installed" = "0" ]; then
|
||||||
|
echo "If need, please input root password to install liblua5.3-dev for build the connector.."
|
||||||
|
sudo apt install -y liblua5.3-dev
|
||||||
|
fi
|
||||||
|
|
||||||
|
gcc -std=c99 lua_connector.c -fPIC -shared -o luaconnector.so -Wall -ltaos -I/usr/include/lua5.3
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,11 @@ struct cb_param{
|
||||||
void * stream;
|
void * stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct async_query_callback_param{
|
||||||
|
lua_State* state;
|
||||||
|
int callback;
|
||||||
|
};
|
||||||
|
|
||||||
static int l_connect(lua_State *L){
|
static int l_connect(lua_State *L){
|
||||||
TAOS * taos=NULL;
|
TAOS * taos=NULL;
|
||||||
const char* host;
|
const char* host;
|
||||||
|
@ -23,7 +28,7 @@ static int l_connect(lua_State *L){
|
||||||
|
|
||||||
luaL_checktype(L, 1, LUA_TTABLE);
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
|
||||||
lua_getfield(L,-1,"host");
|
lua_getfield(L, 1,"host");
|
||||||
if (lua_isstring(L,-1)){
|
if (lua_isstring(L,-1)){
|
||||||
host = lua_tostring(L, -1);
|
host = lua_tostring(L, -1);
|
||||||
// printf("host = %s\n", host);
|
// printf("host = %s\n", host);
|
||||||
|
@ -178,6 +183,58 @@ static int l_query(lua_State *L){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void async_query_callback(void *param, TAOS_RES *result, int code){
|
||||||
|
struct async_query_callback_param* p = (struct async_query_callback_param*) param;
|
||||||
|
|
||||||
|
//printf("\nin c,numfields:%d\n", numFields);
|
||||||
|
//printf("\nin c, code:%d\n", code);
|
||||||
|
|
||||||
|
lua_State *L = p->state;
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, p->callback);
|
||||||
|
lua_newtable(L);
|
||||||
|
int table_index = lua_gettop(L);
|
||||||
|
if( code < 0){
|
||||||
|
printf("failed, reason:%s\n", taos_errstr(result));
|
||||||
|
lua_pushinteger(L, -1);
|
||||||
|
lua_setfield(L, table_index, "code");
|
||||||
|
lua_pushstring(L,"something is wrong");// taos_errstr(taos));
|
||||||
|
lua_setfield(L, table_index, "error");
|
||||||
|
}else{
|
||||||
|
//printf("success to async query.\n");
|
||||||
|
const int affectRows = taos_affected_rows(result);
|
||||||
|
//printf(" affect rows:%d\r\n", affectRows);
|
||||||
|
lua_pushinteger(L, 0);
|
||||||
|
lua_setfield(L, table_index, "code");
|
||||||
|
lua_pushinteger(L, affectRows);
|
||||||
|
lua_setfield(L, table_index, "affected");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_call(L, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_async_query(lua_State *L){
|
||||||
|
int r = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
TAOS * taos = (TAOS*)lua_topointer(L,1);
|
||||||
|
const char * sqlstr = lua_tostring(L,2);
|
||||||
|
// int stime = luaL_checknumber(L,3);
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
int table_index = lua_gettop(L);
|
||||||
|
|
||||||
|
struct async_query_callback_param *p = malloc(sizeof(struct async_query_callback_param));
|
||||||
|
p->state = L;
|
||||||
|
p->callback=r;
|
||||||
|
// printf("r:%d, L:%d\n",r,L);
|
||||||
|
taos_query_a(taos,sqlstr,async_query_callback,p);
|
||||||
|
|
||||||
|
lua_pushnumber(L, 0);
|
||||||
|
lua_setfield(L, table_index, "code");
|
||||||
|
lua_pushstring(L, "ok");
|
||||||
|
lua_setfield(L, table_index, "error");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void stream_cb(void *param, TAOS_RES *result, TAOS_ROW row){
|
void stream_cb(void *param, TAOS_RES *result, TAOS_ROW row){
|
||||||
struct cb_param* p = (struct cb_param*) param;
|
struct cb_param* p = (struct cb_param*) param;
|
||||||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
TAOS_FIELD *fields = taos_fetch_fields(result);
|
||||||
|
@ -308,6 +365,7 @@ static int l_close(lua_State *L){
|
||||||
static const struct luaL_Reg lib[] = {
|
static const struct luaL_Reg lib[] = {
|
||||||
{"connect", l_connect},
|
{"connect", l_connect},
|
||||||
{"query", l_query},
|
{"query", l_query},
|
||||||
|
{"query_a",l_async_query},
|
||||||
{"close", l_close},
|
{"close", l_close},
|
||||||
{"open_stream", l_open_stream},
|
{"open_stream", l_open_stream},
|
||||||
{"close_stream", l_close_stream},
|
{"close_stream", l_close_stream},
|
||||||
|
|
|
@ -13,6 +13,11 @@ struct cb_param{
|
||||||
void * stream;
|
void * stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct async_query_callback_param{
|
||||||
|
lua_State* state;
|
||||||
|
int callback;
|
||||||
|
};
|
||||||
|
|
||||||
static int l_connect(lua_State *L){
|
static int l_connect(lua_State *L){
|
||||||
TAOS * taos=NULL;
|
TAOS * taos=NULL;
|
||||||
const char* host;
|
const char* host;
|
||||||
|
@ -56,6 +61,7 @@ static int l_connect(lua_State *L){
|
||||||
lua_settop(L,0);
|
lua_settop(L,0);
|
||||||
|
|
||||||
taos_init();
|
taos_init();
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
int table_index = lua_gettop(L);
|
int table_index = lua_gettop(L);
|
||||||
|
|
||||||
|
@ -177,6 +183,58 @@ static int l_query(lua_State *L){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void async_query_callback(void *param, TAOS_RES *result, int code){
|
||||||
|
struct async_query_callback_param* p = (struct async_query_callback_param*) param;
|
||||||
|
|
||||||
|
//printf("\nin c,numfields:%d\n", numFields);
|
||||||
|
//printf("\nin c, code:%d\n", code);
|
||||||
|
|
||||||
|
lua_State *L = p->state;
|
||||||
|
lua_rawgeti(L, LUA_REGISTRYINDEX, p->callback);
|
||||||
|
lua_newtable(L);
|
||||||
|
int table_index = lua_gettop(L);
|
||||||
|
if( code < 0){
|
||||||
|
printf("failed, reason:%s\n", taos_errstr(result));
|
||||||
|
lua_pushinteger(L, -1);
|
||||||
|
lua_setfield(L, table_index, "code");
|
||||||
|
lua_pushstring(L,"something is wrong");// taos_errstr(taos));
|
||||||
|
lua_setfield(L, table_index, "error");
|
||||||
|
}else{
|
||||||
|
//printf("success to async query.\n");
|
||||||
|
const int affectRows = taos_affected_rows(result);
|
||||||
|
//printf(" affect rows:%d\r\n", affectRows);
|
||||||
|
lua_pushinteger(L, 0);
|
||||||
|
lua_setfield(L, table_index, "code");
|
||||||
|
lua_pushinteger(L, affectRows);
|
||||||
|
lua_setfield(L, table_index, "affected");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_call(L, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_async_query(lua_State *L){
|
||||||
|
int r = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||||
|
TAOS * taos = (TAOS*)lua_topointer(L,1);
|
||||||
|
const char * sqlstr = lua_tostring(L,2);
|
||||||
|
// int stime = luaL_checknumber(L,3);
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
int table_index = lua_gettop(L);
|
||||||
|
|
||||||
|
struct async_query_callback_param *p = malloc(sizeof(struct async_query_callback_param));
|
||||||
|
p->state = L;
|
||||||
|
p->callback=r;
|
||||||
|
// printf("r:%d, L:%d\n",r,L);
|
||||||
|
taos_query_a(taos,sqlstr,async_query_callback,p);
|
||||||
|
|
||||||
|
lua_pushnumber(L, 0);
|
||||||
|
lua_setfield(L, table_index, "code");
|
||||||
|
lua_pushstring(L, "ok");
|
||||||
|
lua_setfield(L, table_index, "error");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void stream_cb(void *param, TAOS_RES *result, TAOS_ROW row){
|
void stream_cb(void *param, TAOS_RES *result, TAOS_ROW row){
|
||||||
struct cb_param* p = (struct cb_param*) param;
|
struct cb_param* p = (struct cb_param*) param;
|
||||||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
TAOS_FIELD *fields = taos_fetch_fields(result);
|
||||||
|
@ -307,6 +365,7 @@ static int l_close(lua_State *L){
|
||||||
static const struct luaL_Reg lib[] = {
|
static const struct luaL_Reg lib[] = {
|
||||||
{"connect", l_connect},
|
{"connect", l_connect},
|
||||||
{"query", l_query},
|
{"query", l_query},
|
||||||
|
{"query_a",l_async_query},
|
||||||
{"close", l_close},
|
{"close", l_close},
|
||||||
{"open_stream", l_open_stream},
|
{"open_stream", l_open_stream},
|
||||||
{"close_stream", l_close_stream},
|
{"close_stream", l_close_stream},
|
||||||
|
|
|
@ -110,7 +110,25 @@ else
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function callback(t)
|
function async_query_callback(res)
|
||||||
|
if res.code ~=0 then
|
||||||
|
print("async_query_callback--- failed:"..res.error)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
|
||||||
|
if(res.affected == 3) then
|
||||||
|
print("async_query_callback, insert records--- pass")
|
||||||
|
else
|
||||||
|
print("async_query_callback, insert records---failed: expect 3 affected records, actually affected "..res.affected)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
driver.query_a(conn,"INSERT INTO therm1 VALUES ('2019-09-01 00:00:00.005', 100),('2019-09-01 00:00:00.006', 101),('2019-09-01 00:00:00.007', 102)", async_query_callback)
|
||||||
|
|
||||||
|
|
||||||
|
function stream_callback(t)
|
||||||
print("------------------------")
|
print("------------------------")
|
||||||
print("continuous query result:")
|
print("continuous query result:")
|
||||||
for key, value in pairs(t) do
|
for key, value in pairs(t) do
|
||||||
|
@ -119,7 +137,7 @@ function callback(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
local stream
|
local stream
|
||||||
res = driver.open_stream(conn,"SELECT COUNT(*) as count, AVG(degree) as avg, MAX(degree) as max, MIN(degree) as min FROM thermometer interval(2s) sliding(2s);)",0,callback)
|
res = driver.open_stream(conn,"SELECT COUNT(*) as count, AVG(degree) as avg, MAX(degree) as max, MIN(degree) as min FROM thermometer interval(2s) sliding(2s);)",0, stream_callback)
|
||||||
if res.code ~=0 then
|
if res.code ~=0 then
|
||||||
print("open stream--- failed:"..res.error)
|
print("open stream--- failed:"..res.error)
|
||||||
return
|
return
|
||||||
|
@ -146,4 +164,5 @@ while loop_index < 30 do
|
||||||
end
|
end
|
||||||
|
|
||||||
driver.close_stream(stream)
|
driver.close_stream(stream)
|
||||||
|
|
||||||
driver.close(conn)
|
driver.close(conn)
|
||||||
|
|
|
@ -29,8 +29,8 @@ pipeline {
|
||||||
agent none
|
agent none
|
||||||
environment{
|
environment{
|
||||||
|
|
||||||
WK = '/var/lib/jenkins/workspace/TDinternal'
|
WK = '/data/lib/jenkins/workspace/TDinternal'
|
||||||
WKC= '/var/lib/jenkins/workspace/TDinternal/community'
|
WKC= '/data/lib/jenkins/workspace/TDinternal/community'
|
||||||
}
|
}
|
||||||
|
|
||||||
stages {
|
stages {
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
from util.dnodes import tdDnodes
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def getBuildPath(self):
|
||||||
|
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
if ("community" in selfPath):
|
||||||
|
projPath = selfPath[:selfPath.find("community")]
|
||||||
|
else:
|
||||||
|
projPath = selfPath[:selfPath.find("tests")]
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(projPath):
|
||||||
|
if ("taosd" in files):
|
||||||
|
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||||
|
if ("packaging" not in rootRealPath):
|
||||||
|
buildPath = root[:len(root) - len("/build/bin")]
|
||||||
|
break
|
||||||
|
return buildPath
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
tdSql.query('show databases')
|
||||||
|
tdSql.checkData(0,15,0)
|
||||||
|
buildPath = self.getBuildPath()
|
||||||
|
if (buildPath == ""):
|
||||||
|
tdLog.exit("taosd not found!")
|
||||||
|
else:
|
||||||
|
tdLog.info("taosd found in %s" % buildPath)
|
||||||
|
binPath = buildPath + "/build/bin/"
|
||||||
|
|
||||||
|
#write 5M rows into db, then restart to force the data move into disk.
|
||||||
|
#create 500 tables
|
||||||
|
os.system("%staosdemo -f tools/taosdemoAllTest/insert_5M_rows.json -y " % binPath)
|
||||||
|
tdDnodes.stop(1)
|
||||||
|
tdDnodes.start(1)
|
||||||
|
tdSql.execute('use db')
|
||||||
|
|
||||||
|
#prepare to query 500 tables last_row()
|
||||||
|
tableName = []
|
||||||
|
for i in range(500):
|
||||||
|
tableName.append(f"stb_{i}")
|
||||||
|
tdSql.execute('use db')
|
||||||
|
lastRow_Off_start = datetime.now()
|
||||||
|
|
||||||
|
slow = 0 #count time where lastRow on is slower
|
||||||
|
for i in range(5):
|
||||||
|
#switch lastRow to off and check
|
||||||
|
tdSql.execute('alter database db cachelast 0')
|
||||||
|
tdSql.query('show databases')
|
||||||
|
tdSql.checkData(0,15,0)
|
||||||
|
|
||||||
|
#run last_row(*) query 500 times
|
||||||
|
for i in range(500):
|
||||||
|
tdSql.execute(f'SELECT LAST_ROW(*) FROM {tableName[i]}')
|
||||||
|
lastRow_Off_end = datetime.now()
|
||||||
|
|
||||||
|
tdLog.debug(f'time used:{lastRow_Off_end-lastRow_Off_start}')
|
||||||
|
|
||||||
|
#switch lastRow to on and check
|
||||||
|
tdSql.execute('alter database db cachelast 1')
|
||||||
|
tdSql.query('show databases')
|
||||||
|
tdSql.checkData(0,15,1)
|
||||||
|
|
||||||
|
#run last_row(*) query 500 times
|
||||||
|
tdSql.execute('use db')
|
||||||
|
lastRow_On_start = datetime.now()
|
||||||
|
for i in range(500):
|
||||||
|
tdSql.execute(f'SELECT LAST_ROW(*) FROM {tableName[i]}')
|
||||||
|
lastRow_On_end = datetime.now()
|
||||||
|
|
||||||
|
tdLog.debug(f'time used:{lastRow_On_end-lastRow_On_start}')
|
||||||
|
|
||||||
|
#check which one used more time
|
||||||
|
if (lastRow_Off_end-lastRow_Off_start > lastRow_On_end-lastRow_On_start):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
slow += 1
|
||||||
|
tdLog.debug(slow)
|
||||||
|
if slow > 1: #tolerance for the first time
|
||||||
|
tdLog.exit('lastRow hot alter failed')
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,73 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def getBuildPath(self):
|
||||||
|
selfPath = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
if ("community" in selfPath):
|
||||||
|
projPath = selfPath[:selfPath.find("community")]
|
||||||
|
else:
|
||||||
|
projPath = selfPath[:selfPath.find("tests")]
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(projPath):
|
||||||
|
if ("taosd" in files):
|
||||||
|
rootRealPath = os.path.dirname(os.path.realpath(root))
|
||||||
|
if ("packaging" not in rootRealPath):
|
||||||
|
buildPath = root[:len(root) - len("/build/bin")]
|
||||||
|
break
|
||||||
|
return buildPath
|
||||||
|
|
||||||
|
def isLuaInstalled(self):
|
||||||
|
if not which('lua'):
|
||||||
|
tdLog.exit("Lua not found!")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
# tdLog.info("Check if Lua installed")
|
||||||
|
# if not self.isLuaInstalled():
|
||||||
|
# sys.exit(1)
|
||||||
|
|
||||||
|
buildPath = self.getBuildPath()
|
||||||
|
if (buildPath == ""):
|
||||||
|
tdLog.exit("taosd not found!")
|
||||||
|
else:
|
||||||
|
tdLog.info("taosd found in %s" % buildPath)
|
||||||
|
|
||||||
|
targetPath = buildPath + "/../tests/examples/lua"
|
||||||
|
tdLog.info(targetPath)
|
||||||
|
currentPath = os.getcwd()
|
||||||
|
os.chdir(targetPath)
|
||||||
|
os.system('./build.sh')
|
||||||
|
os.system('lua test.lua')
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
#tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -37,6 +37,7 @@ import requests
|
||||||
import gc
|
import gc
|
||||||
import taos
|
import taos
|
||||||
|
|
||||||
|
|
||||||
from .shared.types import TdColumns, TdTags
|
from .shared.types import TdColumns, TdTags
|
||||||
|
|
||||||
# from crash_gen import ServiceManager, TdeInstance, TdeSubProcess
|
# from crash_gen import ServiceManager, TdeInstance, TdeSubProcess
|
||||||
|
@ -160,6 +161,7 @@ class WorkerThread:
|
||||||
Logging.debug("[TRD] Thread Coordinator not running any more, worker thread now stopping...")
|
Logging.debug("[TRD] Thread Coordinator not running any more, worker thread now stopping...")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
# Before we fetch the task and run it, let's ensure we properly "use" the database (not needed any more)
|
# Before we fetch the task and run it, let's ensure we properly "use" the database (not needed any more)
|
||||||
try:
|
try:
|
||||||
if (Config.getConfig().per_thread_db_connection): # most likely TRUE
|
if (Config.getConfig().per_thread_db_connection): # most likely TRUE
|
||||||
|
@ -1362,9 +1364,12 @@ class Task():
|
||||||
Progress.emit(Progress.ACCEPTABLE_ERROR)
|
Progress.emit(Progress.ACCEPTABLE_ERROR)
|
||||||
self._err = err
|
self._err = err
|
||||||
else: # not an acceptable error
|
else: # not an acceptable error
|
||||||
errMsg = "[=] Unexpected Taos library exception ({}): errno=0x{:X}, msg: {}, SQL: {}".format(
|
shortTid = threading.get_ident() % 10000
|
||||||
|
errMsg = "[=] Unexpected Taos library exception ({}): errno=0x{:X}, thread={}, msg: {}, SQL: {}".format(
|
||||||
self.__class__.__name__,
|
self.__class__.__name__,
|
||||||
errno2, err, wt.getDbConn().getLastSql())
|
errno2,
|
||||||
|
shortTid,
|
||||||
|
err, wt.getDbConn().getLastSql())
|
||||||
self.logDebug(errMsg)
|
self.logDebug(errMsg)
|
||||||
if Config.getConfig().debug:
|
if Config.getConfig().debug:
|
||||||
# raise # so that we see full stack
|
# raise # so that we see full stack
|
||||||
|
@ -1411,11 +1416,15 @@ class Task():
|
||||||
|
|
||||||
def lockTable(self, ftName): # full table name
|
def lockTable(self, ftName): # full table name
|
||||||
# print(" <<" + ftName + '_', end="", flush=True)
|
# print(" <<" + ftName + '_', end="", flush=True)
|
||||||
with Task._lock:
|
with Task._lock: # SHORT lock! so we only protect lock creation
|
||||||
if not ftName in Task._tableLocks:
|
if not ftName in Task._tableLocks: # Create new lock and add to list, if needed
|
||||||
Task._tableLocks[ftName] = threading.Lock()
|
Task._tableLocks[ftName] = threading.Lock()
|
||||||
|
|
||||||
Task._tableLocks[ftName].acquire()
|
# No lock protection, anybody can do this any time
|
||||||
|
lock = Task._tableLocks[ftName]
|
||||||
|
# Logging.info("Acquiring lock: {}, {}".format(ftName, lock))
|
||||||
|
lock.acquire()
|
||||||
|
# Logging.info("Acquiring lock successful: {}".format(lock))
|
||||||
|
|
||||||
def unlockTable(self, ftName):
|
def unlockTable(self, ftName):
|
||||||
# print('_' + ftName + ">> ", end="", flush=True)
|
# print('_' + ftName + ">> ", end="", flush=True)
|
||||||
|
@ -1425,7 +1434,13 @@ class Task():
|
||||||
lock = Task._tableLocks[ftName]
|
lock = Task._tableLocks[ftName]
|
||||||
if not lock.locked():
|
if not lock.locked():
|
||||||
raise RuntimeError("Corrupte state, already unlocked")
|
raise RuntimeError("Corrupte state, already unlocked")
|
||||||
|
|
||||||
|
# Important note, we want to protect unlocking under the task level
|
||||||
|
# locking, because we don't want the lock to be deleted (maybe in the futur)
|
||||||
|
# while we unlock it
|
||||||
|
# Logging.info("Releasing lock: {}".format(lock))
|
||||||
lock.release()
|
lock.release()
|
||||||
|
# Logging.info("Releasing lock successful: {}".format(lock))
|
||||||
|
|
||||||
|
|
||||||
class ExecutionStats:
|
class ExecutionStats:
|
||||||
|
@ -1696,6 +1711,11 @@ class TdSuperTable:
|
||||||
return dbc.query("SELECT * FROM {}.{}".format(self._dbName, self._stName)) > 0
|
return dbc.query("SELECT * FROM {}.{}".format(self._dbName, self._stName)) > 0
|
||||||
|
|
||||||
def ensureRegTable(self, task: Optional[Task], dbc: DbConn, regTableName: str):
|
def ensureRegTable(self, task: Optional[Task], dbc: DbConn, regTableName: str):
|
||||||
|
'''
|
||||||
|
Make sure a regular table exists for this super table, creating it if necessary.
|
||||||
|
If there is an associated "Task" that wants to do this, "lock" this table so that
|
||||||
|
others don't access it while we create it.
|
||||||
|
'''
|
||||||
dbName = self._dbName
|
dbName = self._dbName
|
||||||
sql = "select tbname from {}.{} where tbname in ('{}')".format(dbName, self._stName, regTableName)
|
sql = "select tbname from {}.{} where tbname in ('{}')".format(dbName, self._stName, regTableName)
|
||||||
if dbc.query(sql) >= 1 : # reg table exists already
|
if dbc.query(sql) >= 1 : # reg table exists already
|
||||||
|
@ -1703,18 +1723,24 @@ class TdSuperTable:
|
||||||
|
|
||||||
# acquire a lock first, so as to be able to *verify*. More details in TD-1471
|
# acquire a lock first, so as to be able to *verify*. More details in TD-1471
|
||||||
fullTableName = dbName + '.' + regTableName
|
fullTableName = dbName + '.' + regTableName
|
||||||
if task is not None: # TODO: what happens if we don't lock the table
|
if task is not None: # Somethime thie operation is requested on behalf of a "task"
|
||||||
task.lockTable(fullTableName)
|
# Logging.info("Locking table for creation: {}".format(fullTableName))
|
||||||
|
task.lockTable(fullTableName) # in which case we'll lock this table to ensure serialized access
|
||||||
|
# Logging.info("Table locked for creation".format(fullTableName))
|
||||||
Progress.emit(Progress.CREATE_TABLE_ATTEMPT) # ATTEMPT to create a new table
|
Progress.emit(Progress.CREATE_TABLE_ATTEMPT) # ATTEMPT to create a new table
|
||||||
# print("(" + fullTableName[-3:] + ")", end="", flush=True)
|
# print("(" + fullTableName[-3:] + ")", end="", flush=True)
|
||||||
try:
|
try:
|
||||||
sql = "CREATE TABLE {} USING {}.{} tags ({})".format(
|
sql = "CREATE TABLE {} USING {}.{} tags ({})".format(
|
||||||
fullTableName, dbName, self._stName, self._getTagStrForSql(dbc)
|
fullTableName, dbName, self._stName, self._getTagStrForSql(dbc)
|
||||||
)
|
)
|
||||||
|
# Logging.info("Creating regular with SQL: {}".format(sql))
|
||||||
dbc.execute(sql)
|
dbc.execute(sql)
|
||||||
|
# Logging.info("Regular table created: {}".format(sql))
|
||||||
finally:
|
finally:
|
||||||
if task is not None:
|
if task is not None:
|
||||||
|
# Logging.info("Unlocking table after creation: {}".format(fullTableName))
|
||||||
task.unlockTable(fullTableName) # no matter what
|
task.unlockTable(fullTableName) # no matter what
|
||||||
|
# Logging.info("Table unlocked after creation: {}".format(fullTableName))
|
||||||
|
|
||||||
def _getTagStrForSql(self, dbc) :
|
def _getTagStrForSql(self, dbc) :
|
||||||
tags = self._getTags(dbc)
|
tags = self._getTags(dbc)
|
||||||
|
@ -2011,9 +2037,30 @@ class TaskAddData(StateTransitionTask):
|
||||||
def canBeginFrom(cls, state: AnyState):
|
def canBeginFrom(cls, state: AnyState):
|
||||||
return state.canAddData()
|
return state.canAddData()
|
||||||
|
|
||||||
|
def _lockTableIfNeeded(self, fullTableName, extraMsg = ''):
|
||||||
|
if Config.getConfig().verify_data:
|
||||||
|
# Logging.info("Locking table: {}".format(fullTableName))
|
||||||
|
self.lockTable(fullTableName)
|
||||||
|
# Logging.info("Table locked {}: {}".format(extraMsg, fullTableName))
|
||||||
|
# print("_w" + str(nextInt % 100), end="", flush=True) # Trace what was written
|
||||||
|
else:
|
||||||
|
# Logging.info("Skipping locking table")
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _unlockTableIfNeeded(self, fullTableName):
|
||||||
|
if Config.getConfig().verify_data:
|
||||||
|
# Logging.info("Unlocking table: {}".format(fullTableName))
|
||||||
|
self.unlockTable(fullTableName)
|
||||||
|
# Logging.info("Table unlocked: {}".format(fullTableName))
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
# Logging.info("Skipping unlocking table")
|
||||||
|
|
||||||
def _addDataInBatch(self, db, dbc, regTableName, te: TaskExecutor):
|
def _addDataInBatch(self, db, dbc, regTableName, te: TaskExecutor):
|
||||||
numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS
|
numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS
|
||||||
|
|
||||||
fullTableName = db.getName() + '.' + regTableName
|
fullTableName = db.getName() + '.' + regTableName
|
||||||
|
self._lockTableIfNeeded(fullTableName, 'batch')
|
||||||
|
|
||||||
sql = "INSERT INTO {} VALUES ".format(fullTableName)
|
sql = "INSERT INTO {} VALUES ".format(fullTableName)
|
||||||
for j in range(numRecords): # number of records per table
|
for j in range(numRecords): # number of records per table
|
||||||
|
@ -2021,51 +2068,60 @@ class TaskAddData(StateTransitionTask):
|
||||||
nextTick = db.getNextTick()
|
nextTick = db.getNextTick()
|
||||||
nextColor = db.getNextColor()
|
nextColor = db.getNextColor()
|
||||||
sql += "('{}', {}, '{}');".format(nextTick, nextInt, nextColor)
|
sql += "('{}', {}, '{}');".format(nextTick, nextInt, nextColor)
|
||||||
|
|
||||||
|
# Logging.info("Adding data in batch: {}".format(sql))
|
||||||
|
try:
|
||||||
dbc.execute(sql)
|
dbc.execute(sql)
|
||||||
|
finally:
|
||||||
|
# Logging.info("Data added in batch: {}".format(sql))
|
||||||
|
self._unlockTableIfNeeded(fullTableName)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _addData(self, db: Database, dbc, regTableName, te: TaskExecutor): # implied: NOT in batches
|
def _addData(self, db: Database, dbc, regTableName, te: TaskExecutor): # implied: NOT in batches
|
||||||
numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS
|
numRecords = self.LARGE_NUMBER_OF_RECORDS if Config.getConfig().larger_data else self.SMALL_NUMBER_OF_RECORDS
|
||||||
|
|
||||||
for j in range(numRecords): # number of records per table
|
for j in range(numRecords): # number of records per table
|
||||||
nextInt = db.getNextInt()
|
intToWrite = db.getNextInt()
|
||||||
nextTick = db.getNextTick()
|
nextTick = db.getNextTick()
|
||||||
nextColor = db.getNextColor()
|
nextColor = db.getNextColor()
|
||||||
if Config.getConfig().record_ops:
|
if Config.getConfig().record_ops:
|
||||||
self.prepToRecordOps()
|
self.prepToRecordOps()
|
||||||
if self.fAddLogReady is None:
|
if self.fAddLogReady is None:
|
||||||
raise CrashGenError("Unexpected empty fAddLogReady")
|
raise CrashGenError("Unexpected empty fAddLogReady")
|
||||||
self.fAddLogReady.write("Ready to write {} to {}\n".format(nextInt, regTableName))
|
self.fAddLogReady.write("Ready to write {} to {}\n".format(intToWrite, regTableName))
|
||||||
self.fAddLogReady.flush()
|
self.fAddLogReady.flush()
|
||||||
os.fsync(self.fAddLogReady.fileno())
|
os.fsync(self.fAddLogReady.fileno())
|
||||||
|
|
||||||
# TODO: too ugly trying to lock the table reliably, refactor...
|
# TODO: too ugly trying to lock the table reliably, refactor...
|
||||||
fullTableName = db.getName() + '.' + regTableName
|
fullTableName = db.getName() + '.' + regTableName
|
||||||
if Config.getConfig().verify_data:
|
self._lockTableIfNeeded(fullTableName) # so that we are verify read-back. TODO: deal with exceptions before unlock
|
||||||
self.lockTable(fullTableName)
|
|
||||||
# print("_w" + str(nextInt % 100), end="", flush=True) # Trace what was written
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sql = "INSERT INTO {} VALUES ('{}', {}, '{}');".format( # removed: tags ('{}', {})
|
sql = "INSERT INTO {} VALUES ('{}', {}, '{}');".format( # removed: tags ('{}', {})
|
||||||
fullTableName,
|
fullTableName,
|
||||||
# ds.getFixedSuperTableName(),
|
# ds.getFixedSuperTableName(),
|
||||||
# ds.getNextBinary(), ds.getNextFloat(),
|
# ds.getNextBinary(), ds.getNextFloat(),
|
||||||
nextTick, nextInt, nextColor)
|
nextTick, intToWrite, nextColor)
|
||||||
|
# Logging.info("Adding data: {}".format(sql))
|
||||||
dbc.execute(sql)
|
dbc.execute(sql)
|
||||||
|
# Logging.info("Data added: {}".format(sql))
|
||||||
|
intWrote = intToWrite
|
||||||
|
|
||||||
# Quick hack, attach an update statement here. TODO: create an "update" task
|
# Quick hack, attach an update statement here. TODO: create an "update" task
|
||||||
if (not Config.getConfig().use_shadow_db) and Dice.throw(5) == 0: # 1 in N chance, plus not using shaddow DB
|
if (not Config.getConfig().use_shadow_db) and Dice.throw(5) == 0: # 1 in N chance, plus not using shaddow DB
|
||||||
nextInt = db.getNextInt()
|
intToUpdate = db.getNextInt() # Updated, but should not succeed
|
||||||
nextColor = db.getNextColor()
|
nextColor = db.getNextColor()
|
||||||
sql = "INSERt INTO {} VALUES ('{}', {}, '{}');".format( # "INSERt" means "update" here
|
sql = "INSERt INTO {} VALUES ('{}', {}, '{}');".format( # "INSERt" means "update" here
|
||||||
fullTableName,
|
fullTableName,
|
||||||
nextTick, nextInt, nextColor)
|
nextTick, intToUpdate, nextColor)
|
||||||
# sql = "UPDATE {} set speed={}, color='{}' WHERE ts='{}'".format(
|
# sql = "UPDATE {} set speed={}, color='{}' WHERE ts='{}'".format(
|
||||||
# fullTableName, db.getNextInt(), db.getNextColor(), nextTick)
|
# fullTableName, db.getNextInt(), db.getNextColor(), nextTick)
|
||||||
dbc.execute(sql)
|
dbc.execute(sql)
|
||||||
|
intWrote = intToUpdate # We updated, seems TDengine non-cluster accepts this.
|
||||||
|
|
||||||
except: # Any exception at all
|
except: # Any exception at all
|
||||||
if Config.getConfig().verify_data:
|
self._unlockTableIfNeeded(fullTableName)
|
||||||
self.unlockTable(fullTableName)
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# Now read it back and verify, we might encounter an error if table is dropped
|
# Now read it back and verify, we might encounter an error if table is dropped
|
||||||
|
@ -2073,33 +2129,41 @@ class TaskAddData(StateTransitionTask):
|
||||||
try:
|
try:
|
||||||
readBack = dbc.queryScalar("SELECT speed from {}.{} WHERE ts='{}'".
|
readBack = dbc.queryScalar("SELECT speed from {}.{} WHERE ts='{}'".
|
||||||
format(db.getName(), regTableName, nextTick))
|
format(db.getName(), regTableName, nextTick))
|
||||||
if readBack != nextInt :
|
if readBack != intWrote :
|
||||||
raise taos.error.ProgrammingError(
|
raise taos.error.ProgrammingError(
|
||||||
"Failed to read back same data, wrote: {}, read: {}"
|
"Failed to read back same data, wrote: {}, read: {}"
|
||||||
.format(nextInt, readBack), 0x999)
|
.format(intWrote, readBack), 0x999)
|
||||||
except taos.error.ProgrammingError as err:
|
except taos.error.ProgrammingError as err:
|
||||||
errno = Helper.convertErrno(err.errno)
|
errno = Helper.convertErrno(err.errno)
|
||||||
if errno in [CrashGenError.INVALID_EMPTY_RESULT, CrashGenError.INVALID_MULTIPLE_RESULT] : # not a single result
|
if errno == CrashGenError.INVALID_EMPTY_RESULT: # empty result
|
||||||
raise taos.error.ProgrammingError(
|
raise taos.error.ProgrammingError(
|
||||||
"Failed to read back same data for tick: {}, wrote: {}, read: {}"
|
"Failed to read back same data for tick: {}, wrote: {}, read: EMPTY"
|
||||||
.format(nextTick, nextInt, "Empty Result" if errno == CrashGenError.INVALID_EMPTY_RESULT else "Multiple Result"),
|
.format(nextTick, intWrote),
|
||||||
|
errno)
|
||||||
|
elif errno == CrashGenError.INVALID_MULTIPLE_RESULT : # multiple results
|
||||||
|
raise taos.error.ProgrammingError(
|
||||||
|
"Failed to read back same data for tick: {}, wrote: {}, read: MULTIPLE RESULTS"
|
||||||
|
.format(nextTick, intWrote),
|
||||||
errno)
|
errno)
|
||||||
elif errno in [0x218, 0x362]: # table doesn't exist
|
elif errno in [0x218, 0x362]: # table doesn't exist
|
||||||
# do nothing
|
# do nothing
|
||||||
dummy = 0
|
pass
|
||||||
else:
|
else:
|
||||||
# Re-throw otherwise
|
# Re-throw otherwise
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
self.unlockTable(fullTableName) # Unlock the table no matter what
|
self._unlockTableIfNeeded(fullTableName) # Quite ugly, refactor lock/unlock
|
||||||
|
# Done with read-back verification, unlock the table now
|
||||||
|
else:
|
||||||
|
self._unlockTableIfNeeded(fullTableName)
|
||||||
|
|
||||||
# Successfully wrote the data into the DB, let's record it somehow
|
# Successfully wrote the data into the DB, let's record it somehow
|
||||||
te.recordDataMark(nextInt)
|
te.recordDataMark(intWrote)
|
||||||
|
|
||||||
if Config.getConfig().record_ops:
|
if Config.getConfig().record_ops:
|
||||||
if self.fAddLogDone is None:
|
if self.fAddLogDone is None:
|
||||||
raise CrashGenError("Unexpected empty fAddLogDone")
|
raise CrashGenError("Unexpected empty fAddLogDone")
|
||||||
self.fAddLogDone.write("Wrote {} to {}\n".format(nextInt, regTableName))
|
self.fAddLogDone.write("Wrote {} to {}\n".format(intWrote, regTableName))
|
||||||
self.fAddLogDone.flush()
|
self.fAddLogDone.flush()
|
||||||
os.fsync(self.fAddLogDone.fileno())
|
os.fsync(self.fAddLogDone.fileno())
|
||||||
|
|
||||||
|
@ -2137,15 +2201,16 @@ class TaskAddData(StateTransitionTask):
|
||||||
class ThreadStacks: # stack info for all threads
|
class ThreadStacks: # stack info for all threads
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._allStacks = {}
|
self._allStacks = {}
|
||||||
allFrames = sys._current_frames()
|
allFrames = sys._current_frames() # All current stack frames
|
||||||
for th in threading.enumerate():
|
for th in threading.enumerate(): # For each thread
|
||||||
if th.ident is None:
|
if th.ident is None:
|
||||||
continue
|
continue
|
||||||
stack = traceback.extract_stack(allFrames[th.ident])
|
stack = traceback.extract_stack(allFrames[th.ident]) # Get stack for a thread
|
||||||
self._allStacks[th.native_id] = stack
|
shortTid = th.ident % 10000
|
||||||
|
self._allStacks[shortTid] = stack # Was using th.native_id
|
||||||
|
|
||||||
def print(self, filteredEndName = None, filterInternal = False):
|
def print(self, filteredEndName = None, filterInternal = False):
|
||||||
for thNid, stack in self._allStacks.items(): # for each thread, stack frames top to bottom
|
for tIdent, stack in self._allStacks.items(): # for each thread, stack frames top to bottom
|
||||||
lastFrame = stack[-1]
|
lastFrame = stack[-1]
|
||||||
if filteredEndName: # we need to filter out stacks that match this name
|
if filteredEndName: # we need to filter out stacks that match this name
|
||||||
if lastFrame.name == filteredEndName : # end did not match
|
if lastFrame.name == filteredEndName : # end did not match
|
||||||
|
@ -2157,7 +2222,7 @@ class ThreadStacks: # stack info for all threads
|
||||||
'__init__']: # the thread that extracted the stack
|
'__init__']: # the thread that extracted the stack
|
||||||
continue # ignore
|
continue # ignore
|
||||||
# Now print
|
# Now print
|
||||||
print("\n<----- Thread Info for LWP/ID: {} (most recent call last) <-----".format(thNid))
|
print("\n<----- Thread Info for LWP/ID: {} (most recent call last) <-----".format(tIdent))
|
||||||
stackFrame = 0
|
stackFrame = 0
|
||||||
for frame in stack: # was using: reversed(stack)
|
for frame in stack: # was using: reversed(stack)
|
||||||
# print(frame)
|
# print(frame)
|
||||||
|
@ -2376,7 +2441,7 @@ class MainExec:
|
||||||
action='store',
|
action='store',
|
||||||
default=0,
|
default=0,
|
||||||
type=int,
|
type=int,
|
||||||
help='Maximum number of DBs to keep, set to disable dropping DB. (default: 0)')
|
help='Number of DBs to use, set to disable dropping DB. (default: 0)')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-c',
|
'-c',
|
||||||
'--connector-type',
|
'--connector-type',
|
||||||
|
|
|
@ -179,7 +179,7 @@ quorum 2
|
||||||
def getServiceCmdLine(self): # to start the instance
|
def getServiceCmdLine(self): # to start the instance
|
||||||
if Config.getConfig().track_memory_leaks:
|
if Config.getConfig().track_memory_leaks:
|
||||||
Logging.info("Invoking VALGRIND on service...")
|
Logging.info("Invoking VALGRIND on service...")
|
||||||
return ['exec /usr/bin/valgrind', '--leak-check=yes', self.getExecFile(), '-c', self.getCfgDir()]
|
return ['exec valgrind', '--leak-check=yes', self.getExecFile(), '-c', self.getCfgDir()]
|
||||||
else:
|
else:
|
||||||
# TODO: move "exec -c" into Popen(), we can both "use shell" and NOT fork so ask to lose kill control
|
# TODO: move "exec -c" into Popen(), we can both "use shell" and NOT fork so ask to lose kill control
|
||||||
return ["exec " + self.getExecFile(), '-c', self.getCfgDir()] # used in subproce.Popen()
|
return ["exec " + self.getExecFile(), '-c', self.getCfgDir()] # used in subproce.Popen()
|
||||||
|
@ -310,7 +310,7 @@ class TdeSubProcess:
|
||||||
# print("Starting TDengine with env: ", myEnv.items())
|
# print("Starting TDengine with env: ", myEnv.items())
|
||||||
print("Starting TDengine: {}".format(cmdLine))
|
print("Starting TDengine: {}".format(cmdLine))
|
||||||
|
|
||||||
return Popen(
|
ret = Popen(
|
||||||
' '.join(cmdLine), # ' '.join(cmdLine) if useShell else cmdLine,
|
' '.join(cmdLine), # ' '.join(cmdLine) if useShell else cmdLine,
|
||||||
shell=True, # Always use shell, since we need to pass ENV vars
|
shell=True, # Always use shell, since we need to pass ENV vars
|
||||||
stdout=PIPE,
|
stdout=PIPE,
|
||||||
|
@ -318,6 +318,10 @@ class TdeSubProcess:
|
||||||
close_fds=ON_POSIX,
|
close_fds=ON_POSIX,
|
||||||
env=myEnv
|
env=myEnv
|
||||||
) # had text=True, which interferred with reading EOF
|
) # had text=True, which interferred with reading EOF
|
||||||
|
time.sleep(0.01) # very brief wait, then let's check if sub process started successfully.
|
||||||
|
if ret.poll():
|
||||||
|
raise CrashGenError("Sub process failed to start with command line: {}".format(cmdLine))
|
||||||
|
return ret
|
||||||
|
|
||||||
STOP_SIGNAL = signal.SIGINT # signal.SIGKILL/SIGINT # What signal to use (in kill) to stop a taosd process?
|
STOP_SIGNAL = signal.SIGINT # signal.SIGKILL/SIGINT # What signal to use (in kill) to stop a taosd process?
|
||||||
SIG_KILL_RETCODE = 137 # ref: https://stackoverflow.com/questions/43268156/process-finished-with-exit-code-137-in-pycharm
|
SIG_KILL_RETCODE = 137 # ref: https://stackoverflow.com/questions/43268156/process-finished-with-exit-code-137-in-pycharm
|
||||||
|
@ -614,7 +618,7 @@ class ServiceManager:
|
||||||
|
|
||||||
# Find if there's already a taosd service, and then kill it
|
# Find if there's already a taosd service, and then kill it
|
||||||
for proc in psutil.process_iter():
|
for proc in psutil.process_iter():
|
||||||
if proc.name() == 'taosd':
|
if proc.name() == 'taosd' or proc.name() == 'memcheck-amd64-': # Regular or under Valgrind
|
||||||
Logging.info("Killing an existing TAOSD process in 2 seconds... press CTRL-C to interrupt")
|
Logging.info("Killing an existing TAOSD process in 2 seconds... press CTRL-C to interrupt")
|
||||||
time.sleep(2.0)
|
time.sleep(2.0)
|
||||||
proc.kill()
|
proc.kill()
|
||||||
|
|
|
@ -35,7 +35,8 @@ class LoggingFilter(logging.Filter):
|
||||||
|
|
||||||
class MyLoggingAdapter(logging.LoggerAdapter):
|
class MyLoggingAdapter(logging.LoggerAdapter):
|
||||||
def process(self, msg, kwargs):
|
def process(self, msg, kwargs):
|
||||||
return "[{:04d}] {}".format(threading.get_ident() % 10000, msg), kwargs
|
shortTid = threading.get_ident() % 10000
|
||||||
|
return "[{:04d}] {}".format(shortTid, msg), kwargs
|
||||||
# return '[%s] %s' % (self.extra['connid'], msg), kwargs
|
# return '[%s] %s' % (self.extra['connid'], msg), kwargs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ python3 ./test.py -f table/column_name.py
|
||||||
python3 ./test.py -f table/column_num.py
|
python3 ./test.py -f table/column_num.py
|
||||||
python3 ./test.py -f table/db_table.py
|
python3 ./test.py -f table/db_table.py
|
||||||
python3 ./test.py -f table/create_sensitive.py
|
python3 ./test.py -f table/create_sensitive.py
|
||||||
#python3 ./test.py -f table/tablename-boundary.py
|
python3 ./test.py -f table/tablename-boundary.py
|
||||||
python3 ./test.py -f table/max_table_length.py
|
python3 ./test.py -f table/max_table_length.py
|
||||||
python3 ./test.py -f table/alter_column.py
|
python3 ./test.py -f table/alter_column.py
|
||||||
python3 ./test.py -f table/boundary.py
|
python3 ./test.py -f table/boundary.py
|
||||||
|
@ -334,5 +334,7 @@ python3 ./test.py -f tag_lite/alter_tag.py
|
||||||
|
|
||||||
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py
|
python3 test.py -f tools/taosdemoAllTest/taosdemoTestInsertWithJson.py
|
||||||
python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py
|
python3 test.py -f tools/taosdemoAllTest/taosdemoTestQueryWithJson.py
|
||||||
|
python3 ./test.py -f tag_lite/drop_auto_create.py
|
||||||
|
python3 test.py -f insert/insert_before_use_db.py
|
||||||
|
python3 test.py -f alter/alter_cacheLastRow.py
|
||||||
#======================p4-end===============
|
#======================p4-end===============
|
||||||
|
|
|
@ -82,6 +82,8 @@ class TDTestCase:
|
||||||
tdSql.execute("import into tbx file \'%s\'"%(self.csvfile))
|
tdSql.execute("import into tbx file \'%s\'"%(self.csvfile))
|
||||||
tdSql.query('select * from tbx')
|
tdSql.query('select * from tbx')
|
||||||
tdSql.checkRows(self.rows)
|
tdSql.checkRows(self.rows)
|
||||||
|
#TD-4447 import the same csv twice
|
||||||
|
tdSql.execute("import into tbx file \'%s\'"%(self.csvfile))
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.destroyCSVFile()
|
self.destroyCSVFile()
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.error('insert into tb values (now + 10m, 10)')
|
||||||
|
tdSql.prepare()
|
||||||
|
tdSql.error('insert into tb values (now + 10m, 10)')
|
||||||
|
tdSql.execute('drop database db')
|
||||||
|
tdSql.error('insert into tb values (now + 10m, 10)')
|
||||||
|
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -37,6 +37,10 @@ class TDTestCase:
|
||||||
|
|
||||||
tdSql.error("insert into tb values (now, 'taosdata001')")
|
tdSql.error("insert into tb values (now, 'taosdata001')")
|
||||||
|
|
||||||
|
tdSql.error("insert into tb(now, 😀)")
|
||||||
|
tdSql.query("select * from tb")
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
tdLog.success("%s successfully executed" % __file__)
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
|
@ -35,3 +35,5 @@ python3.8 ./test.py $1 -s && sleep 1
|
||||||
python3.8 ./test.py $1 -f client/client.py
|
python3.8 ./test.py $1 -f client/client.py
|
||||||
python3.8 ./test.py $1 -s && sleep 1
|
python3.8 ./test.py $1 -s && sleep 1
|
||||||
|
|
||||||
|
# connector
|
||||||
|
python3.8 ./test.py $1 -f connector/lua.py
|
||||||
|
|
|
@ -14,6 +14,13 @@ class TDTestCase:
|
||||||
tdLog.debug("start to execute %s" % __file__)
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
tdSql.init(conn.cursor(), logSql)
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
self.ts = 1622100000000
|
||||||
|
|
||||||
|
def get_random_string(self, length):
|
||||||
|
letters = string.ascii_lowercase
|
||||||
|
result_str = ''.join(random.choice(letters) for i in range(length))
|
||||||
|
return result_str
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
tdSql.prepare()
|
tdSql.prepare()
|
||||||
|
|
||||||
|
@ -24,20 +31,63 @@ class TDTestCase:
|
||||||
shell=True)) - 1
|
shell=True)) - 1
|
||||||
tdLog.info("table name max length is %d" % tableNameMaxLen)
|
tdLog.info("table name max length is %d" % tableNameMaxLen)
|
||||||
chars = string.ascii_uppercase + string.ascii_lowercase
|
chars = string.ascii_uppercase + string.ascii_lowercase
|
||||||
tb_name = ''.join(random.choices(chars, k=tableNameMaxLen))
|
tb_name = ''.join(random.choices(chars, k=tableNameMaxLen + 1))
|
||||||
tdLog.info('tb_name length %d' % len(tb_name))
|
tdLog.info('tb_name length %d' % len(tb_name))
|
||||||
tdLog.info('create table %s (ts timestamp, value int)' % tb_name)
|
tdLog.info('create table %s (ts timestamp, value int)' % tb_name)
|
||||||
tdSql.error(
|
tdSql.error('create table %s (ts timestamp, speed binary(4089))' % tb_name)
|
||||||
'create table %s (ts timestamp, speed binary(4089))' %
|
|
||||||
tb_name)
|
|
||||||
|
|
||||||
tb_name = ''.join(random.choices(chars, k=191))
|
tb_name = ''.join(random.choices(chars, k=tableNameMaxLen))
|
||||||
tdLog.info('tb_name length %d' % len(tb_name))
|
tdLog.info('tb_name length %d' % len(tb_name))
|
||||||
tdLog.info('create table %s (ts timestamp, value int)' % tb_name)
|
tdLog.info('create table %s (ts timestamp, value int)' % tb_name)
|
||||||
tdSql.execute(
|
tdSql.execute(
|
||||||
'create table %s (ts timestamp, speed binary(4089))' %
|
'create table %s (ts timestamp, speed binary(4089))' %
|
||||||
tb_name)
|
tb_name)
|
||||||
|
|
||||||
|
db_name = self.get_random_string(33)
|
||||||
|
tdSql.error("create database %s" % db_name)
|
||||||
|
|
||||||
|
db_name = self.get_random_string(32)
|
||||||
|
tdSql.execute("create database %s" % db_name)
|
||||||
|
tdSql.execute("use %s" % db_name)
|
||||||
|
|
||||||
|
tb_name = self.get_random_string(193)
|
||||||
|
tdSql.error("create table %s(ts timestamp, val int)" % tb_name)
|
||||||
|
|
||||||
|
tb_name = self.get_random_string(192)
|
||||||
|
tdSql.execute("create table %s.%s(ts timestamp, val int)" % (db_name, tb_name))
|
||||||
|
tdSql.query("show %s.tables" % db_name)
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
tdSql.checkData(0, 0, tb_name)
|
||||||
|
|
||||||
|
tdSql.execute("insert into %s.%s values(now, 1)" % (db_name, tb_name))
|
||||||
|
tdSql.query("select * from %s.%s" %(db_name, tb_name))
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
db_name = self.get_random_string(32)
|
||||||
|
tdSql.execute("create database %s update 1" % db_name)
|
||||||
|
|
||||||
|
stb_name = self.get_random_string(192)
|
||||||
|
tdSql.execute("create table %s.%s(ts timestamp, val int) tags(id int)" % (db_name, stb_name))
|
||||||
|
tb_name1 = self.get_random_string(192)
|
||||||
|
tdSql.execute("insert into %s.%s using %s.%s tags(1) values(%d, 1)(%d, 2)(%d, 3)" % (db_name, tb_name1, db_name, stb_name, self.ts, self.ts + 1, self.ts + 2))
|
||||||
|
tb_name2 = self.get_random_string(192)
|
||||||
|
tdSql.execute("insert into %s.%s using %s.%s tags(2) values(%d, 1)(%d, 2)(%d, 3)" % (db_name, tb_name2, db_name, stb_name, self.ts, self.ts + 1, self.ts + 2))
|
||||||
|
|
||||||
|
tdSql.query("show %s.tables" % db_name)
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
|
tdSql.query("select * from %s.%s" % (db_name, stb_name))
|
||||||
|
tdSql.checkRows(6)
|
||||||
|
|
||||||
|
tdSql.execute("insert into %s.%s using %s.%s tags(1) values(%d, null)" % (db_name, tb_name1, db_name, stb_name, self.ts))
|
||||||
|
|
||||||
|
tdSql.query("select * from %s.%s" % (db_name, stb_name))
|
||||||
|
tdSql.checkRows(6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
tdSql.close()
|
tdSql.close()
|
||||||
tdLog.success("%s successfully executed" % __file__)
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
def init(self, conn, logSql):
|
||||||
|
tdLog.debug("start to execute %s" % __file__)
|
||||||
|
tdSql.init(conn.cursor(), logSql)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
tdSql.prepare()
|
||||||
|
|
||||||
|
tdSql.execute('create table m1(ts timestamp, k int) tags(a binary(12), b int, c double);')
|
||||||
|
tdSql.execute('insert into tm0 using m1(b,c) tags(1, 99) values(now, 1);')
|
||||||
|
tdSql.execute('insert into tm1 using m1(b,c) tags(2, 100) values(now, 2);')
|
||||||
|
tdLog.info("2 rows inserted")
|
||||||
|
tdSql.query('select * from m1;')
|
||||||
|
tdSql.checkRows(2)
|
||||||
|
tdSql.query('select *,tbname from m1;')
|
||||||
|
tdSql.execute("drop table tm0; ")
|
||||||
|
tdSql.query('select * from m1')
|
||||||
|
tdSql.checkRows(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success("%s successfully executed" % __file__)
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,60 @@
|
||||||
|
{
|
||||||
|
"filetype": "insert",
|
||||||
|
"cfgdir": "/etc/taos",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"port": 6030,
|
||||||
|
"user": "root",
|
||||||
|
"password": "taosdata",
|
||||||
|
"thread_count": 4,
|
||||||
|
"thread_count_create_tbl": 4,
|
||||||
|
"result_file": "./insert_res.txt",
|
||||||
|
"confirm_parameter_prompt": "no",
|
||||||
|
"insert_interval": 0,
|
||||||
|
"interlace_rows": 100,
|
||||||
|
"num_of_records_per_req": 100,
|
||||||
|
"databases": [{
|
||||||
|
"dbinfo": {
|
||||||
|
"name": "db",
|
||||||
|
"drop": "yes",
|
||||||
|
"replica": 1,
|
||||||
|
"days": 10,
|
||||||
|
"cache": 16,
|
||||||
|
"blocks": 8,
|
||||||
|
"precision": "ms",
|
||||||
|
"keep": 3650,
|
||||||
|
"minRows": 100,
|
||||||
|
"maxRows": 4096,
|
||||||
|
"comp":2,
|
||||||
|
"walLevel":1,
|
||||||
|
"cachelast":0,
|
||||||
|
"quorum":1,
|
||||||
|
"fsync":3000,
|
||||||
|
"update": 0
|
||||||
|
},
|
||||||
|
"super_tables": [{
|
||||||
|
"name": "stb",
|
||||||
|
"child_table_exists":"no",
|
||||||
|
"childtable_count": 500,
|
||||||
|
"childtable_prefix": "stb_",
|
||||||
|
"auto_create_table": "no",
|
||||||
|
"batch_create_tbl_num": 20,
|
||||||
|
"data_source": "rand",
|
||||||
|
"insert_mode": "taosc",
|
||||||
|
"insert_rows": 10000,
|
||||||
|
"childtable_limit": 10,
|
||||||
|
"childtable_offset":100,
|
||||||
|
"interlace_rows": 0,
|
||||||
|
"insert_interval":0,
|
||||||
|
"max_sql_len": 1024000,
|
||||||
|
"disorder_ratio": 0,
|
||||||
|
"disorder_range": 1000,
|
||||||
|
"timestamp_step": 10,
|
||||||
|
"start_timestamp": "2020-10-01 00:00:00.000",
|
||||||
|
"sample_format": "csv",
|
||||||
|
"sample_file": "./sample.csv",
|
||||||
|
"tags_file": "",
|
||||||
|
"columns": [{"type": "INT"}],
|
||||||
|
"tags": [{"type": "TINYINT", "count":2}]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}
|
|
@ -432,7 +432,7 @@ class TDDnodes:
|
||||||
self.simDeployed = False
|
self.simDeployed = False
|
||||||
|
|
||||||
def init(self, path):
|
def init(self, path):
|
||||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
psCmd = "ps -ef|grep -w taosd| grep -v grep| grep -v defunct | awk '{print $2}'"
|
||||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||||
while(processID):
|
while(processID):
|
||||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||||
|
@ -545,14 +545,14 @@ class TDDnodes:
|
||||||
for i in range(len(self.dnodes)):
|
for i in range(len(self.dnodes)):
|
||||||
self.dnodes[i].stop()
|
self.dnodes[i].stop()
|
||||||
|
|
||||||
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep | awk '{print $2}'"
|
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep| grep -v defunct | awk '{print $2}'"
|
||||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||||
if processID:
|
if processID:
|
||||||
cmd = "sudo systemctl stop taosd"
|
cmd = "sudo systemctl stop taosd"
|
||||||
os.system(cmd)
|
os.system(cmd)
|
||||||
# if os.system(cmd) != 0 :
|
# if os.system(cmd) != 0 :
|
||||||
# tdLog.exit(cmd)
|
# tdLog.exit(cmd)
|
||||||
psCmd = "ps -ef|grep -w taosd| grep -v grep | awk '{print $2}'"
|
psCmd = "ps -ef|grep -w taosd| grep -v grep| grep -v defunct | awk '{print $2}'"
|
||||||
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
|
||||||
while(processID):
|
while(processID):
|
||||||
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
killCmd = "kill -TERM %s > /dev/null 2>&1" % processID
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,6 +24,9 @@ sql drop database if exists $db
|
||||||
sql create database $db keep 36500
|
sql create database $db keep 36500
|
||||||
sql use $db
|
sql use $db
|
||||||
|
|
||||||
|
print =====================================> td-4481
|
||||||
|
sql create database $db
|
||||||
|
|
||||||
print =====================================> test case for twa in single block
|
print =====================================> test case for twa in single block
|
||||||
|
|
||||||
sql create table t1 (ts timestamp, k float);
|
sql create table t1 (ts timestamp, k float);
|
||||||
|
|
|
@ -9,7 +9,7 @@ sql connect
|
||||||
|
|
||||||
print ======================== dnode1 start
|
print ======================== dnode1 start
|
||||||
|
|
||||||
$dbPrefix = nest_query
|
$dbPrefix = nest_db
|
||||||
$tbPrefix = nest_tb
|
$tbPrefix = nest_tb
|
||||||
$mtPrefix = nest_mt
|
$mtPrefix = nest_mt
|
||||||
$tbNum = 10
|
$tbNum = 10
|
||||||
|
@ -17,7 +17,6 @@ $rowNum = 10000
|
||||||
$totalNum = $tbNum * $rowNum
|
$totalNum = $tbNum * $rowNum
|
||||||
|
|
||||||
print =============== nestquery.sim
|
print =============== nestquery.sim
|
||||||
|
|
||||||
$i = 0
|
$i = 0
|
||||||
$db = $dbPrefix . $i
|
$db = $dbPrefix . $i
|
||||||
$mt = $mtPrefix . $i
|
$mt = $mtPrefix . $i
|
||||||
|
|
|
@ -60,4 +60,5 @@ run general/parser/slimit_alter_tags.sim
|
||||||
run general/parser/binary_escapeCharacter.sim
|
run general/parser/binary_escapeCharacter.sim
|
||||||
run general/parser/between_and.sim
|
run general/parser/between_and.sim
|
||||||
run general/parser/last_cache.sim
|
run general/parser/last_cache.sim
|
||||||
|
run general/parser/nestquery.sim
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue