[td-10564] refactor and add test cases.
This commit is contained in:
parent
3f84c37db3
commit
a531411e06
|
@ -81,6 +81,7 @@ extern const int32_t TYPE_BYTES[15];
|
||||||
#define TSDB_ERR -1
|
#define TSDB_ERR -1
|
||||||
|
|
||||||
#define TS_PATH_DELIMITER "."
|
#define TS_PATH_DELIMITER "."
|
||||||
|
#define TS_ESCAPE_CHAR '`'
|
||||||
|
|
||||||
#define TSDB_TIME_PRECISION_MILLI 0
|
#define TSDB_TIME_PRECISION_MILLI 0
|
||||||
#define TSDB_TIME_PRECISION_MICRO 1
|
#define TSDB_TIME_PRECISION_MICRO 1
|
||||||
|
|
|
@ -26,6 +26,7 @@ extern "C" {
|
||||||
#include "tdef.h"
|
#include "tdef.h"
|
||||||
|
|
||||||
int32_t strdequote(char *src);
|
int32_t strdequote(char *src);
|
||||||
|
int32_t strndequote(char *dst, const char* z, int32_t len);
|
||||||
int32_t strRmquote(char *z, int32_t len);
|
int32_t strRmquote(char *z, int32_t len);
|
||||||
size_t strtrim(char *src);
|
size_t strtrim(char *src);
|
||||||
char * strnchr(char *haystack, char needle, int32_t len, bool skipquote);
|
char * strnchr(char *haystack, char needle, int32_t len, bool skipquote);
|
||||||
|
|
|
@ -4349,10 +4349,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 1
|
// 1
|
||||||
"sum",
|
"sum",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_SUM,
|
FUNCTION_SUM,
|
||||||
FUNCTION_SUM,
|
FUNCTION_SUM,
|
||||||
BASIC_FUNC_SO,
|
BASIC_FUNC_SO,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
sum_function,
|
sum_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4362,10 +4362,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 2
|
// 2
|
||||||
"avg",
|
"avg",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_AVG,
|
FUNCTION_AVG,
|
||||||
FUNCTION_AVG,
|
FUNCTION_AVG,
|
||||||
BASIC_FUNC_SO,
|
BASIC_FUNC_SO,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
avg_function,
|
avg_function,
|
||||||
avg_finalizer,
|
avg_finalizer,
|
||||||
|
@ -4375,10 +4375,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 3
|
// 3
|
||||||
"min",
|
"min",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_MIN,
|
FUNCTION_MIN,
|
||||||
FUNCTION_MIN,
|
FUNCTION_MIN,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
min_func_setup,
|
min_func_setup,
|
||||||
min_function,
|
min_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4388,10 +4388,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 4
|
// 4
|
||||||
"max",
|
"max",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_MAX,
|
FUNCTION_MAX,
|
||||||
FUNCTION_MAX,
|
FUNCTION_MAX,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
max_func_setup,
|
max_func_setup,
|
||||||
max_function,
|
max_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4401,10 +4401,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 5
|
// 5
|
||||||
"stddev",
|
"stddev",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_STDDEV,
|
FUNCTION_STDDEV,
|
||||||
FUNCTION_STDDEV_DST,
|
FUNCTION_STDDEV_DST,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STREAM,
|
FUNCSTATE_SO | FUNCSTATE_STREAM,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
stddev_function,
|
stddev_function,
|
||||||
stddev_finalizer,
|
stddev_finalizer,
|
||||||
|
@ -4414,10 +4414,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 6
|
// 6
|
||||||
"percentile",
|
"percentile",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_PERCT,
|
FUNCTION_PERCT,
|
||||||
FUNCTION_INVALID_ID,
|
FUNCTION_INVALID_ID,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STREAM,
|
FUNCSTATE_SO | FUNCSTATE_STREAM,
|
||||||
FUNCTION_AGG,
|
|
||||||
percentile_function_setup,
|
percentile_function_setup,
|
||||||
percentile_function,
|
percentile_function,
|
||||||
percentile_finalizer,
|
percentile_finalizer,
|
||||||
|
@ -4427,10 +4427,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 7
|
// 7
|
||||||
"apercentile",
|
"apercentile",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_APERCT,
|
FUNCTION_APERCT,
|
||||||
FUNCTION_APERCT,
|
FUNCTION_APERCT,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STREAM | FUNCSTATE_STABLE,
|
FUNCSTATE_SO | FUNCSTATE_STREAM | FUNCSTATE_STABLE,
|
||||||
FUNCTION_AGG,
|
|
||||||
apercentile_function_setup,
|
apercentile_function_setup,
|
||||||
apercentile_function,
|
apercentile_function,
|
||||||
apercentile_finalizer,
|
apercentile_finalizer,
|
||||||
|
@ -4440,10 +4440,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 8
|
// 8
|
||||||
"first",
|
"first",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_FIRST,
|
FUNCTION_FIRST,
|
||||||
FUNCTION_FIRST_DST,
|
FUNCTION_FIRST_DST,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
first_function,
|
first_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4453,10 +4453,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 9
|
// 9
|
||||||
"last",
|
"last",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_LAST,
|
FUNCTION_LAST,
|
||||||
FUNCTION_LAST_DST,
|
FUNCTION_LAST_DST,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
last_function,
|
last_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4466,10 +4466,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 10
|
// 10
|
||||||
"last_row",
|
"last_row",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_LAST_ROW,
|
FUNCTION_LAST_ROW,
|
||||||
FUNCTION_LAST_ROW,
|
FUNCTION_LAST_ROW,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
FUNCSTATE_SO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
first_last_function_setup,
|
first_last_function_setup,
|
||||||
last_row_function,
|
last_row_function,
|
||||||
last_row_finalizer,
|
last_row_finalizer,
|
||||||
|
@ -4479,10 +4479,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 11
|
// 11
|
||||||
"top",
|
"top",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TOP,
|
FUNCTION_TOP,
|
||||||
FUNCTION_TOP,
|
FUNCTION_TOP,
|
||||||
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
top_bottom_function_setup,
|
top_bottom_function_setup,
|
||||||
top_function,
|
top_function,
|
||||||
top_bottom_func_finalizer,
|
top_bottom_func_finalizer,
|
||||||
|
@ -4492,10 +4492,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 12
|
// 12
|
||||||
"bottom",
|
"bottom",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_BOTTOM,
|
FUNCTION_BOTTOM,
|
||||||
FUNCTION_BOTTOM,
|
FUNCTION_BOTTOM,
|
||||||
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
top_bottom_function_setup,
|
top_bottom_function_setup,
|
||||||
bottom_function,
|
bottom_function,
|
||||||
top_bottom_func_finalizer,
|
top_bottom_func_finalizer,
|
||||||
|
@ -4505,10 +4505,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 13
|
// 13
|
||||||
"spread",
|
"spread",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_SPREAD,
|
FUNCTION_SPREAD,
|
||||||
FUNCTION_SPREAD,
|
FUNCTION_SPREAD,
|
||||||
BASIC_FUNC_SO,
|
BASIC_FUNC_SO,
|
||||||
FUNCTION_AGG,
|
|
||||||
spread_function_setup,
|
spread_function_setup,
|
||||||
spread_function,
|
spread_function,
|
||||||
spread_function_finalizer,
|
spread_function_finalizer,
|
||||||
|
@ -4518,10 +4518,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 14
|
// 14
|
||||||
"twa",
|
"twa",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TWA,
|
FUNCTION_TWA,
|
||||||
FUNCTION_TWA,
|
FUNCTION_TWA,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
twa_function_setup,
|
twa_function_setup,
|
||||||
twa_function,
|
twa_function,
|
||||||
twa_function_finalizer,
|
twa_function_finalizer,
|
||||||
|
@ -4531,10 +4531,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 15
|
// 15
|
||||||
"leastsquares",
|
"leastsquares",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_LEASTSQR,
|
FUNCTION_LEASTSQR,
|
||||||
FUNCTION_INVALID_ID,
|
FUNCTION_INVALID_ID,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STREAM,
|
FUNCSTATE_SO | FUNCSTATE_STREAM,
|
||||||
FUNCTION_AGG,
|
|
||||||
leastsquares_function_setup,
|
leastsquares_function_setup,
|
||||||
leastsquares_function,
|
leastsquares_function,
|
||||||
leastsquares_finalizer,
|
leastsquares_finalizer,
|
||||||
|
@ -4544,10 +4544,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 16
|
// 16
|
||||||
"ts",
|
"ts",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TS,
|
FUNCTION_TS,
|
||||||
FUNCTION_TS,
|
FUNCTION_TS,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
date_col_output_function,
|
date_col_output_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4557,10 +4557,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 17
|
// 17
|
||||||
"ts",
|
"ts",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TS_DUMMY,
|
FUNCTION_TS_DUMMY,
|
||||||
FUNCTION_TS_DUMMY,
|
FUNCTION_TS_DUMMY,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
noop1,
|
noop1,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4570,10 +4570,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 18
|
// 18
|
||||||
"tag_dummy",
|
"tag_dummy",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TAG_DUMMY,
|
FUNCTION_TAG_DUMMY,
|
||||||
FUNCTION_TAG_DUMMY,
|
FUNCTION_TAG_DUMMY,
|
||||||
BASIC_FUNC_SO,
|
BASIC_FUNC_SO,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
tag_function,
|
tag_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4583,10 +4583,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 19
|
// 19
|
||||||
"ts",
|
"ts",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TS_COMP,
|
FUNCTION_TS_COMP,
|
||||||
FUNCTION_TS_COMP,
|
FUNCTION_TS_COMP,
|
||||||
FUNCSTATE_MO | FUNCSTATE_NEED_TS,
|
FUNCSTATE_MO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
ts_comp_function_setup,
|
ts_comp_function_setup,
|
||||||
ts_comp_function,
|
ts_comp_function,
|
||||||
ts_comp_finalize,
|
ts_comp_finalize,
|
||||||
|
@ -4596,10 +4596,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 20
|
// 20
|
||||||
"tag",
|
"tag",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TAG,
|
FUNCTION_TAG,
|
||||||
FUNCTION_TAG,
|
FUNCTION_TAG,
|
||||||
BASIC_FUNC_SO,
|
BASIC_FUNC_SO,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
tag_function,
|
tag_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4609,10 +4609,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{//TODO this is a scala function
|
{//TODO this is a scala function
|
||||||
// 21, column project sql function
|
// 21, column project sql function
|
||||||
"colprj",
|
"colprj",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_PRJ,
|
FUNCTION_PRJ,
|
||||||
FUNCTION_PRJ,
|
FUNCTION_PRJ,
|
||||||
BASIC_FUNC_MO | FUNCSTATE_NEED_TS,
|
BASIC_FUNC_MO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
col_project_function,
|
col_project_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4622,10 +4622,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 22, multi-output, tag function has only one result
|
// 22, multi-output, tag function has only one result
|
||||||
"tagprj",
|
"tagprj",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TAGPRJ,
|
FUNCTION_TAGPRJ,
|
||||||
FUNCTION_TAGPRJ,
|
FUNCTION_TAGPRJ,
|
||||||
BASIC_FUNC_MO,
|
BASIC_FUNC_MO,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
tag_project_function,
|
tag_project_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4635,10 +4635,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 23
|
// 23
|
||||||
"arithmetic",
|
"arithmetic",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_ARITHM,
|
FUNCTION_ARITHM,
|
||||||
FUNCTION_ARITHM,
|
FUNCTION_ARITHM,
|
||||||
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS,
|
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
arithmetic_function,
|
arithmetic_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4648,10 +4648,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 24
|
// 24
|
||||||
"diff",
|
"diff",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_DIFF,
|
FUNCTION_DIFF,
|
||||||
FUNCTION_INVALID_ID,
|
FUNCTION_INVALID_ID,
|
||||||
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
diff_function_setup,
|
diff_function_setup,
|
||||||
diff_function,
|
diff_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4662,10 +4662,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 25
|
// 25
|
||||||
"first_dist",
|
"first_dist",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_FIRST_DST,
|
FUNCTION_FIRST_DST,
|
||||||
FUNCTION_FIRST_DST,
|
FUNCTION_FIRST_DST,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
first_last_function_setup,
|
first_last_function_setup,
|
||||||
first_dist_function,
|
first_dist_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4675,10 +4675,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 26
|
// 26
|
||||||
"last_dist",
|
"last_dist",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_LAST_DST,
|
FUNCTION_LAST_DST,
|
||||||
FUNCTION_LAST_DST,
|
FUNCTION_LAST_DST,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
first_last_function_setup,
|
first_last_function_setup,
|
||||||
last_dist_function,
|
last_dist_function,
|
||||||
function_finalizer,
|
function_finalizer,
|
||||||
|
@ -4688,10 +4688,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 27
|
// 27
|
||||||
"stddev", // return table id and the corresponding tags for join match and subscribe
|
"stddev", // return table id and the corresponding tags for join match and subscribe
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_STDDEV_DST,
|
FUNCTION_STDDEV_DST,
|
||||||
FUNCTION_AVG,
|
FUNCTION_AVG,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STABLE,
|
FUNCSTATE_SO | FUNCSTATE_STABLE,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
stddev_dst_function,
|
stddev_dst_function,
|
||||||
stddev_dst_finalizer,
|
stddev_dst_finalizer,
|
||||||
|
@ -4701,10 +4701,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 28
|
// 28
|
||||||
"interp",
|
"interp",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_INTERP,
|
FUNCTION_INTERP,
|
||||||
FUNCTION_INTERP,
|
FUNCTION_INTERP,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS ,
|
FUNCSTATE_SO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS ,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
interp_function,
|
interp_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4714,10 +4714,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 29
|
// 29
|
||||||
"rate",
|
"rate",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_RATE,
|
FUNCTION_RATE,
|
||||||
FUNCTION_RATE,
|
FUNCTION_RATE,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
rate_function_setup,
|
rate_function_setup,
|
||||||
rate_function,
|
rate_function,
|
||||||
rate_finalizer,
|
rate_finalizer,
|
||||||
|
@ -4727,10 +4727,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 30
|
// 30
|
||||||
"irate",
|
"irate",
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_IRATE,
|
FUNCTION_IRATE,
|
||||||
FUNCTION_IRATE,
|
FUNCTION_IRATE,
|
||||||
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
BASIC_FUNC_SO | FUNCSTATE_NEED_TS,
|
||||||
FUNCTION_AGG,
|
|
||||||
rate_function_setup,
|
rate_function_setup,
|
||||||
irate_function,
|
irate_function,
|
||||||
rate_finalizer,
|
rate_finalizer,
|
||||||
|
@ -4740,10 +4740,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 31
|
// 31
|
||||||
"tbid", // return table id and the corresponding tags for join match and subscribe
|
"tbid", // return table id and the corresponding tags for join match and subscribe
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_TID_TAG,
|
FUNCTION_TID_TAG,
|
||||||
FUNCTION_TID_TAG,
|
FUNCTION_TID_TAG,
|
||||||
FUNCSTATE_MO | FUNCSTATE_STABLE,
|
FUNCSTATE_MO | FUNCSTATE_STABLE,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
noop1,
|
noop1,
|
||||||
noop1,
|
noop1,
|
||||||
|
@ -4752,10 +4752,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
},
|
},
|
||||||
{ //32
|
{ //32
|
||||||
"derivative", // return table id and the corresponding tags for join match and subscribe
|
"derivative", // return table id and the corresponding tags for join match and subscribe
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_DERIVATIVE,
|
FUNCTION_DERIVATIVE,
|
||||||
FUNCTION_INVALID_ID,
|
FUNCTION_INVALID_ID,
|
||||||
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY,
|
||||||
FUNCTION_AGG,
|
|
||||||
deriv_function_setup,
|
deriv_function_setup,
|
||||||
deriv_function,
|
deriv_function,
|
||||||
doFinalizer,
|
doFinalizer,
|
||||||
|
@ -4765,10 +4765,10 @@ SAggFunctionInfo aggFunc[34] = {{
|
||||||
{
|
{
|
||||||
// 33
|
// 33
|
||||||
"_block_dist", // return table id and the corresponding tags for join match and subscribe
|
"_block_dist", // return table id and the corresponding tags for join match and subscribe
|
||||||
|
FUNCTION_AGG,
|
||||||
FUNCTION_BLKINFO,
|
FUNCTION_BLKINFO,
|
||||||
FUNCTION_BLKINFO,
|
FUNCTION_BLKINFO,
|
||||||
FUNCSTATE_SO | FUNCSTATE_STABLE,
|
FUNCSTATE_SO | FUNCSTATE_STABLE,
|
||||||
FUNCTION_AGG,
|
|
||||||
function_setup,
|
function_setup,
|
||||||
blockInfo_func,
|
blockInfo_func,
|
||||||
blockinfo_func_finalizer,
|
blockinfo_func_finalizer,
|
||||||
|
|
|
@ -12,13 +12,16 @@ static void doInitFunctionHashTable() {
|
||||||
functionHashTable = taosHashInit(numOfEntries, MurmurHash3_32, false, false);
|
functionHashTable = taosHashInit(numOfEntries, MurmurHash3_32, false, false);
|
||||||
for (int32_t i = 0; i < numOfEntries; i++) {
|
for (int32_t i = 0; i < numOfEntries; i++) {
|
||||||
int32_t len = (uint32_t)strlen(aggFunc[i].name);
|
int32_t len = (uint32_t)strlen(aggFunc[i].name);
|
||||||
taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&aggFunc[i], POINTER_BYTES);
|
|
||||||
|
SAggFunctionInfo* ptr = &aggFunc[i];
|
||||||
|
taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
numOfEntries = tListLen(scalarFunc);
|
numOfEntries = tListLen(scalarFunc);
|
||||||
for(int32_t i = 0; i < numOfEntries; ++i) {
|
for(int32_t i = 0; i < numOfEntries; ++i) {
|
||||||
int32_t len = (int32_t) strlen(scalarFunc[i].name);
|
int32_t len = (int32_t) strlen(scalarFunc[i].name);
|
||||||
taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&scalarFunc[i], POINTER_BYTES);
|
SScalarFunctionInfo* ptr = &scalarFunc[i];
|
||||||
|
taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,6 @@ typedef struct SSqlExpr {
|
||||||
SColIndex colInfo;
|
SColIndex colInfo;
|
||||||
uint64_t uid; // table uid, todo refactor use the pointer
|
uint64_t uid; // table uid, todo refactor use the pointer
|
||||||
int32_t interBytes; // inter result buffer size
|
int32_t interBytes; // inter result buffer size
|
||||||
// int16_t colType; // table column type
|
|
||||||
// int16_t colBytes; // table column bytes
|
|
||||||
int16_t numOfParams; // argument value of each function
|
int16_t numOfParams; // argument value of each function
|
||||||
SVariant param[3]; // parameters are not more than 3
|
SVariant param[3]; // parameters are not more than 3
|
||||||
} SSqlExpr;
|
} SSqlExpr;
|
||||||
|
@ -101,6 +99,9 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ
|
||||||
*/
|
*/
|
||||||
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
|
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
|
||||||
|
|
||||||
|
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
|
||||||
|
void initQueryInfo(SQueryStmtInfo* pQueryInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract request meta info from the sql statement
|
* Extract request meta info from the sql statement
|
||||||
* @param pSqlInfo
|
* @param pSqlInfo
|
||||||
|
|
|
@ -37,7 +37,7 @@ extern "C" {
|
||||||
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
|
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
|
||||||
|
|
||||||
TAOS_FIELD createField(const SSchema* pSchema);
|
TAOS_FIELD createField(const SSchema* pSchema);
|
||||||
void setSchemaVal(SSchema* pSchema, uint8_t type, int16_t bytes, int16_t colId, const char* name);
|
SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name);
|
||||||
|
|
||||||
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field);
|
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field);
|
||||||
int32_t getNumOfFields(SFieldInfo* pFieldInfo);
|
int32_t getNumOfFields(SFieldInfo* pFieldInfo);
|
||||||
|
@ -45,7 +45,7 @@ SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index);
|
||||||
|
|
||||||
int32_t parserValidateIdToken(SToken* pToken);
|
int32_t parserValidateIdToken(SToken* pToken);
|
||||||
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
||||||
int32_t parserSetSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr);
|
int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr);
|
||||||
|
|
||||||
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
||||||
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
|
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
|
||||||
|
@ -60,6 +60,8 @@ SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid);
|
||||||
void cleanupTagCond(STagCond* pTagCond);
|
void cleanupTagCond(STagCond* pTagCond);
|
||||||
void cleanupColumnCond(SArray** pCond);
|
void cleanupColumnCond(SArray** pCond);
|
||||||
|
|
||||||
|
uint32_t convertRelationalOperator(SToken *pToken);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,8 +30,10 @@ SSchema *getTableTagSchema(const STableMeta* pTableMeta);
|
||||||
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
|
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
|
||||||
|
|
||||||
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
|
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
|
||||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex,
|
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
|
||||||
SSchema* pResSchema, int16_t interSize);
|
|
||||||
|
SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema);
|
||||||
|
|
||||||
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
|
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
|
||||||
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
|
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
|
||||||
void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
|
void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
|
||||||
|
|
|
@ -13,9 +13,8 @@
|
||||||
* 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 <function.h>
|
|
||||||
#include "astGenerator.h"
|
|
||||||
#include "function.h"
|
#include "function.h"
|
||||||
|
#include "astGenerator.h"
|
||||||
#include "parserInt.h"
|
#include "parserInt.h"
|
||||||
#include "parserUtil.h"
|
#include "parserUtil.h"
|
||||||
#include "queryInfoUtil.h"
|
#include "queryInfoUtil.h"
|
||||||
|
@ -34,16 +33,15 @@
|
||||||
|
|
||||||
static int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool outerQuery, SMsgBuf* pMsgBuf);
|
static int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool outerQuery, SMsgBuf* pMsgBuf);
|
||||||
|
|
||||||
void getColumnName(tSqlExprItem* pItem, char* resColumnName, char* rawName, int32_t nameLength) {
|
void setTokenAndResColumnName(tSqlExprItem* pItem, char* resColumnName, char* rawName, int32_t nameLength) {
|
||||||
memset(resColumnName, 0, nameLength);
|
memset(resColumnName, 0, nameLength);
|
||||||
|
|
||||||
int32_t len = ((int32_t)pItem->pNode->exprToken.n < nameLength) ? (int32_t)pItem->pNode->exprToken.n : nameLength;
|
int32_t len = ((int32_t)pItem->pNode->exprToken.n < nameLength) ? (int32_t)pItem->pNode->exprToken.n : nameLength;
|
||||||
strncpy(rawName, pItem->pNode->exprToken.z, len);
|
strncpy(rawName, pItem->pNode->exprToken.z, len);
|
||||||
|
|
||||||
if (pItem->aliasName != NULL) {
|
if (pItem->aliasName != NULL) {
|
||||||
int32_t aliasNameLen = (int32_t) strlen(pItem->aliasName);
|
assert(strlen(pItem->aliasName) < nameLength);
|
||||||
len = (aliasNameLen < nameLength)? aliasNameLen:nameLength;
|
tstrncpy(resColumnName, pItem->aliasName, len);
|
||||||
strncpy(resColumnName, pItem->aliasName, len);
|
|
||||||
} else {
|
} else {
|
||||||
strncpy(resColumnName, rawName, len);
|
strncpy(resColumnName, rawName, len);
|
||||||
}
|
}
|
||||||
|
@ -227,12 +225,7 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initQueryInfo(SQueryStmtInfo* pQueryInfo) {
|
void initQueryInfo(SQueryStmtInfo* pQueryInfo) {
|
||||||
assert(pQueryInfo->fieldsInfo.internalField == NULL);
|
pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField));
|
||||||
//assert(0);
|
|
||||||
// pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField));
|
|
||||||
|
|
||||||
assert(pQueryInfo->exprList == NULL);
|
|
||||||
|
|
||||||
pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES);
|
pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES);
|
||||||
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
|
||||||
pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX;
|
pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX;
|
||||||
|
@ -245,8 +238,6 @@ void initQueryInfo(SQueryStmtInfo* pQueryInfo) {
|
||||||
pQueryInfo->window = TSWINDOW_INITIALIZER;
|
pQueryInfo->window = TSWINDOW_INITIALIZER;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
|
|
||||||
|
|
||||||
static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
|
static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
|
||||||
SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index);
|
SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index);
|
||||||
|
|
||||||
|
@ -653,7 +644,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
const char* msg8 = "condition missing for join query";
|
const char* msg8 = "condition missing for join query";
|
||||||
|
|
||||||
int32_t code = TSDB_CODE_SUCCESS;
|
int32_t code = TSDB_CODE_SUCCESS;
|
||||||
STableMetaInfo *pTableMetaInfo = addEmptyMetaInfo(pQueryInfo);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handle the sql expression without from subclause
|
* handle the sql expression without from subclause
|
||||||
|
@ -751,15 +741,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable group result mixed up if interval/session window query exists.
|
|
||||||
// if (isTimeWindowQuery(pQueryInfo)) {
|
|
||||||
// size_t num = taosArrayGetSize(pQueryInfo->pUpstream);
|
|
||||||
// for(int32_t i = 0; i < num; ++i) {
|
|
||||||
// SQueryStmtInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, i);
|
|
||||||
// pUp->multigroupResult = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// parse the having clause in the first place
|
// parse the having clause in the first place
|
||||||
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
|
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
|
||||||
if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
|
if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
|
||||||
|
@ -776,13 +757,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
|
||||||
// return code;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// updateFunctionInterBuf(pQueryInfo, false);
|
|
||||||
// updateLastScanOrderIfNeeded(pQueryInfo);
|
|
||||||
|
|
||||||
if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -794,6 +768,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
|
||||||
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||||
|
|
||||||
int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY;
|
int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY;
|
||||||
|
@ -846,16 +821,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (tscQueryTags(pQueryInfo)) {
|
|
||||||
// SExprInfo* pExpr1 = getExprInfo(pQueryInfo, 0);
|
|
||||||
//
|
|
||||||
// if (pExpr1->base.functionId != FUNCTION_TID_TAG) {
|
|
||||||
// if ((pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0) || IS_TSWINDOW_SPECIFIED(pQueryInfo->window)) {
|
|
||||||
// return buildInvalidOperationMsg(pMsgBuf, msg5);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// parse the having clause in the first place
|
// parse the having clause in the first place
|
||||||
if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
|
if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) !=
|
||||||
TSDB_CODE_SUCCESS) {
|
TSDB_CODE_SUCCESS) {
|
||||||
|
@ -880,29 +845,10 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
|
|
||||||
// return buildInvalidOperationMsg(pMsgBuf, msg1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // in case of join query, time range is required.
|
|
||||||
// if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
|
||||||
// uint64_t timeRange = (uint64_t)pQueryInfo->window.ekey - pQueryInfo->window.skey;
|
|
||||||
// if (timeRange == 0 && pQueryInfo->window.skey == 0) {
|
|
||||||
// return buildInvalidOperationMsg(pMsgBuf, msg3);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ((code = validateLimitNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
if ((code = validateLimitNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo,pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
|
||||||
// return code;
|
|
||||||
// }
|
|
||||||
// updateLastScanOrderIfNeeded(pQueryInfo);
|
|
||||||
// tscFieldInfoUpdateOffset(pQueryInfo);
|
|
||||||
// updateFunctionInterBuf(pQueryInfo, isSTable);
|
|
||||||
|
|
||||||
if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -911,7 +857,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
||||||
// set the query info
|
// set the query info
|
||||||
SExprInfo** p = NULL;
|
SExprInfo** p = NULL;
|
||||||
int32_t numOfExpr = 0;
|
int32_t numOfExpr = 0;
|
||||||
pTableMetaInfo = getMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = getMetaInfo(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);
|
||||||
|
@ -948,18 +894,8 @@ static int32_t getNewResColId() {
|
||||||
return resColId++;
|
return resColId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t addResColumnInfo(SQueryStmtInfo* pQueryInfo, int32_t outputIndex, SColumnIndex* pColIndex, SSchema* pSchema, SExprInfo* pSqlExpr) {
|
int32_t addResColumnInfo(SQueryStmtInfo* pQueryInfo, int32_t outputIndex, SSchema* pSchema, SExprInfo* pSqlExpr) {
|
||||||
int32_t tableIndex = pColIndex->tableIndex;
|
|
||||||
STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[tableIndex]->pTableMeta;
|
|
||||||
|
|
||||||
assert(pColIndex->columnIndex < getNumOfColumns(pTableMeta));
|
|
||||||
|
|
||||||
uint64_t uid = pTableMeta->uid;
|
|
||||||
SSchema* pSchema1 = getOneColumnSchema(pTableMeta, pColIndex->columnIndex);
|
|
||||||
columnListInsert(pQueryInfo->colList, pColIndex->columnIndex, uid, pSchema1);
|
|
||||||
|
|
||||||
SInternalField* pInfo = insertFieldInfo(&pQueryInfo->fieldsInfo, outputIndex, pSchema);
|
SInternalField* pInfo = insertFieldInfo(&pQueryInfo->fieldsInfo, outputIndex, pSchema);
|
||||||
|
|
||||||
pInfo->pExpr = pSqlExpr;
|
pInfo->pExpr = pSqlExpr;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -990,33 +926,29 @@ void setResultColName(char* name, tSqlExprItem* pItem, SToken* pToken, SToken* f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SExprInfo* addExprInSelect(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex,
|
SExprInfo* doAddOneExprInfo(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex,
|
||||||
SSchema* pColSchema) {
|
SSchema* pColSchema, const char* token) {
|
||||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex);
|
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex);
|
||||||
|
|
||||||
SSchema resultSchema = {0};
|
SSchema resultSchema = createSchema(pColSchema->type, pColSchema->bytes, getNewResColId(), pColSchema->name);
|
||||||
setSchemaVal(&resultSchema, pColSchema->type, pColSchema->bytes, getNewResColId(), pColSchema->name);
|
|
||||||
|
|
||||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, &resultSchema, 0);
|
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, NULL, &resultSchema, 0);
|
||||||
addExprInfo(pQueryInfo, outputColIndex, pExpr);
|
addExprInfo(pQueryInfo, outputColIndex, pExpr);
|
||||||
|
|
||||||
tstrncpy(pExpr->base.token, pColSchema->name, sizeof(pExpr->base.token));
|
tstrncpy(pExpr->base.token, token, sizeof(pExpr->base.token));
|
||||||
|
|
||||||
pExpr->base.colInfo.flag = pIndex->type;
|
pExpr->base.colInfo.flag = pIndex->type;
|
||||||
if (TSDB_COL_IS_TAG(pIndex->type)) {
|
|
||||||
columnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema);
|
columnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema);
|
||||||
} else {
|
addResColumnInfo(pQueryInfo, outputColIndex, pColSchema, pExpr);
|
||||||
addResColumnInfo(pQueryInfo, outputColIndex, pIndex, pColSchema, pExpr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pExpr;
|
return pExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* index, int32_t outputIndex, SExprInfo* pExpr, SSchema* pColSchema, bool finalResult) {
|
void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* index, int32_t outputIndex, SExprInfo* pExpr, SSchema* pColSchema, bool finalResult) {
|
||||||
if (finalResult) {
|
|
||||||
addResColumnInfo(pQueryInfo, outputIndex, index, &pExpr->base.resSchema, pExpr);
|
|
||||||
} else {
|
|
||||||
columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema);
|
columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema);
|
||||||
|
|
||||||
|
if (finalResult) {
|
||||||
|
addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TSDB_COL_IS_NORMAL_COL(index->type)) {
|
if (TSDB_COL_IS_NORMAL_COL(index->type)) {
|
||||||
|
@ -1024,7 +956,7 @@ void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* inde
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t setExprInfoForFunctions(SQueryStmtInfo* pQueryInfo, SSchema* pSchema, int32_t functionId,
|
static int32_t setMultipleExprsInSelect(SQueryStmtInfo* pQueryInfo, SSchema* pSchema, int32_t functionId,
|
||||||
const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult,
|
const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult,
|
||||||
SMsgBuf* pMsgBuf) {
|
SMsgBuf* pMsgBuf) {
|
||||||
const char* msg1 = "not support column types";
|
const char* msg1 = "not support column types";
|
||||||
|
@ -1041,16 +973,63 @@ static int32_t setExprInfoForFunctions(SQueryStmtInfo* pQueryInfo, SSchema* pSch
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
|
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
|
||||||
|
|
||||||
SSchema resultSchema = {0};
|
SSchema resultSchema = createSchema(resType, resBytes, getNewResColId(), name);
|
||||||
setSchemaVal(&resultSchema, resType, resBytes, getNewResColId(), name);
|
|
||||||
|
|
||||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pColIndex, &resultSchema, interBufSize);
|
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pColIndex, NULL, &resultSchema, interBufSize);
|
||||||
addExprInfo(pQueryInfo, resColIdx, pExpr);
|
addExprInfo(pQueryInfo, resColIdx, pExpr);
|
||||||
|
tstrncpy(pExpr->base.token, resultSchema.name, tListLen(pExpr->base.token));
|
||||||
|
|
||||||
doAddResColumnOrSourceColumn(pQueryInfo, pColIndex, resColIdx, pExpr, pSchema, finalResult);
|
doAddResColumnOrSourceColumn(pQueryInfo, pColIndex, resColIdx, pExpr, pSchema, finalResult);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t checkForAliasName(SMsgBuf* pMsgBuf, char* aliasName) {
|
||||||
|
const char* msg1 = "column alias name too long";
|
||||||
|
if (aliasName != NULL && strlen(aliasName) >= TSDB_COL_NAME_LEN) {
|
||||||
|
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t validateComplexExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf);
|
||||||
|
static int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryStmtInfo* pQueryInfo, SArray* pCols, uint64_t *uid, SMsgBuf* pMsgBuf);
|
||||||
|
|
||||||
|
static int64_t getTickPerSecond(SVariant* pVariant, int32_t precision, int64_t* tickPerSec, SMsgBuf *pMsgBuf) {
|
||||||
|
const char* msg10 = "derivative duration should be greater than 1 Second";
|
||||||
|
|
||||||
|
if (taosVariantDump(pVariant, (char*) tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (precision == TSDB_TIME_PRECISION_MILLI) {
|
||||||
|
*tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MICRO);
|
||||||
|
} else if (precision == TSDB_TIME_PRECISION_MICRO) {
|
||||||
|
*tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MILLI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*tickPerSec <= 0 || *tickPerSec < TSDB_TICK_PER_SECOND(precision)) {
|
||||||
|
return buildInvalidOperationMsg(pMsgBuf, msg10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the first column ts for top/bottom query
|
||||||
|
static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, int32_t outputIndex, int32_t tableIndex) {
|
||||||
|
SColumnIndex indexTS = {.tableIndex = tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_COL_NORMAL};
|
||||||
|
SSchema s = createSchema(TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts");
|
||||||
|
|
||||||
|
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, NULL, &s, TSDB_KEYSIZE);
|
||||||
|
addExprInfo(pQueryInfo, outputIndex, pExpr);
|
||||||
|
|
||||||
|
SSchema* pSourceSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, indexTS.columnIndex);
|
||||||
|
columnListInsert(pQueryInfo->colList, indexTS.columnIndex, pTableMetaInfo->pTableMeta->uid, pSourceSchema);
|
||||||
|
addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t multiColumnListInsert(SQueryStmtInfo* pQueryInfo, SArray* pColumnList, SMsgBuf* pMsgBuf);
|
||||||
|
|
||||||
int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult, SMsgBuf* pMsgBuf) {
|
int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult, SMsgBuf* pMsgBuf) {
|
||||||
STableMetaInfo* pTableMetaInfo = NULL;
|
STableMetaInfo* pTableMetaInfo = NULL;
|
||||||
int32_t functionId = pItem->functionId;
|
int32_t functionId = pItem->functionId;
|
||||||
|
@ -1067,6 +1046,11 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
const char* msg10 = "derivative duration should be greater than 1 Second";
|
const char* msg10 = "derivative duration should be greater than 1 Second";
|
||||||
const char* msg11 = "third parameter in derivative should be 0 or 1";
|
const char* msg11 = "third parameter in derivative should be 0 or 1";
|
||||||
const char* msg12 = "parameter is out of range [1, 100]";
|
const char* msg12 = "parameter is out of range [1, 100]";
|
||||||
|
const char* msg13 = "nested function is not supported";
|
||||||
|
|
||||||
|
if (checkForAliasName(pMsgBuf, pItem->aliasName) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
switch (functionId) {
|
switch (functionId) {
|
||||||
case FUNCTION_COUNT: {
|
case FUNCTION_COUNT: {
|
||||||
|
@ -1102,23 +1086,19 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
if (getColumnIndexByName(pToken, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
if (getColumnIndexByName(pToken, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
|
||||||
}
|
}
|
||||||
} else { // count(*) is equalled to count(primary_timestamp_key)
|
} else { // count(*) is equalled to count(primary_timestamp_key)
|
||||||
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false};
|
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo validate.....
|
|
||||||
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||||
SSchema s = {0};
|
SSchema s = createSchema(TSDB_DATA_TYPE_BIGINT, size, getNewResColId(), "");
|
||||||
setSchemaVal(&s, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(), "");
|
|
||||||
|
|
||||||
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, size);
|
|
||||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
|
||||||
|
|
||||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token,sizeof(pExpr->base.resSchema.name) - 1);
|
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, size);
|
||||||
|
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||||
|
|
||||||
|
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token,sizeof(pExpr->base.resSchema.name) - 1);
|
||||||
|
|
||||||
int32_t outputColumnIndex = getNumOfFields(&pQueryInfo->fieldsInfo);
|
int32_t outputColumnIndex = getNumOfFields(&pQueryInfo->fieldsInfo);
|
||||||
SSchema* ps = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
SSchema* ps = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||||
|
@ -1148,37 +1128,66 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
}
|
}
|
||||||
|
|
||||||
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
|
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
|
||||||
if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) {
|
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
tExprNode* pNode = NULL;
|
||||||
|
int32_t tokenId = pParamElem->pNode->tokenId;
|
||||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
|
SSchema columnSchema = {0};
|
||||||
|
|
||||||
|
if (tokenId == TK_ALL || tokenId == TK_ID) { // simple parameter
|
||||||
if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) {
|
if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
|
||||||
STableComInfo info = getTableInfo(pTableMetaInfo->pTableMeta);
|
|
||||||
|
|
||||||
// functions can not be applied to tags
|
// functions can not be applied to tags
|
||||||
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || (index.columnIndex >= getNumOfColumns(pTableMetaInfo->pTableMeta))) {
|
if (TSDB_COL_IS_TAG(index.type)) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. check if sql function can be applied on this column data type
|
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
|
||||||
|
|
||||||
if (!IS_NUMERIC_TYPE(pSchema->type)) {
|
// 2. check if sql function can be applied on this column data type
|
||||||
|
columnSchema = *(SSchema*) getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||||
|
|
||||||
|
if (!IS_NUMERIC_TYPE(columnSchema.type)) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE)) {
|
} else if (IS_UNSIGNED_NUMERIC_TYPE(columnSchema.type) && (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE)) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg9);
|
return buildInvalidOperationMsg(pMsgBuf, msg9);
|
||||||
}
|
}
|
||||||
|
} else if (tokenId == TK_PLUS || tokenId == TK_MINUS || tokenId == TK_TIMES || tokenId == TK_REM || tokenId == TK_CONCAT) {
|
||||||
|
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||||
|
SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex));
|
||||||
|
if (validateComplexExpr(pParamElem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||||
|
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arithmeticType != NORMAL_ARITHMETIC) {
|
||||||
|
return buildInvalidOperationMsg(pMsgBuf, msg13);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTableMetaInfo = getMetaInfo(pQueryInfo, 0); // get the first table meta.
|
||||||
|
columnSchema = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
|
||||||
|
|
||||||
|
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||||
|
int32_t ret = sqlExprToExprNode(&pNode, pItem->pNode, pQueryInfo, colList, NULL, pMsgBuf);
|
||||||
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
|
taosArrayDestroy(colList);
|
||||||
|
tExprTreeDestroy(pNode, NULL);
|
||||||
|
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
multiColumnListInsert(pQueryInfo, pColumnList, pMsgBuf);
|
||||||
|
} else {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t precision = pTableMetaInfo->pTableMeta->tableInfo.precision;
|
||||||
|
|
||||||
int16_t resultType = 0;
|
int16_t resultType = 0;
|
||||||
int16_t resultSize = 0;
|
int16_t resultSize = 0;
|
||||||
int32_t intermediateResSize = 0;
|
int32_t intermediateResSize = 0;
|
||||||
|
|
||||||
if (getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize,
|
if (getResultDataInfo(columnSchema.type, columnSchema.bytes, functionId, 0, &resultType, &resultSize,
|
||||||
&intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
|
&intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
@ -1186,23 +1195,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
// set the first column ts for diff query
|
// set the first column ts for diff query
|
||||||
int32_t numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
|
int32_t numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
|
||||||
if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) {
|
if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) {
|
||||||
SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0, .type = TSDB_COL_NORMAL};
|
setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, numOfOutput, index.tableIndex);
|
||||||
SSchema s = {0};
|
|
||||||
setSchemaVal(&s, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts");
|
|
||||||
|
|
||||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, &s, TSDB_KEYSIZE);
|
|
||||||
addExprInfo(pQueryInfo, numOfOutput, pExpr);
|
|
||||||
|
|
||||||
//todo set the correct result field name
|
|
||||||
assert(numOfOutput == 0);
|
|
||||||
addResColumnInfo(pQueryInfo, numOfOutput, &index, &pExpr->base.resSchema, pExpr);
|
|
||||||
numOfOutput += 1;
|
numOfOutput += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema s = {0};
|
SSchema s = createSchema(resultType, resultSize, getNewResColId(), "ts");
|
||||||
setSchemaVal(&s, resultType, resultSize, getNewResColId(), "ts");
|
|
||||||
|
|
||||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, intermediateResSize);
|
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, pNode, &s, intermediateResSize);
|
||||||
addExprInfo(pQueryInfo, numOfOutput, pExpr);
|
addExprInfo(pQueryInfo, numOfOutput, pExpr);
|
||||||
|
|
||||||
if (functionId == FUNCTION_LEASTSQR) { // set the leastsquares parameters
|
if (functionId == FUNCTION_LEASTSQR) { // set the leastsquares parameters
|
||||||
|
@ -1220,23 +1219,14 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
|
|
||||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
|
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES);
|
||||||
} else if (functionId == FUNCTION_IRATE) {
|
} else if (functionId == FUNCTION_IRATE) {
|
||||||
addExprInfoParam(&pExpr->base, (char*) &info.precision, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
addExprInfoParam(&pExpr->base, (char*) &precision, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
||||||
} else if (functionId == FUNCTION_DERIVATIVE) {
|
} else if (functionId == FUNCTION_DERIVATIVE) {
|
||||||
char val[8] = {0};
|
char val[8] = {0};
|
||||||
|
|
||||||
int64_t tickPerSec = 0;
|
int64_t tickPerSec = 0;
|
||||||
if (taosVariantDump(&pParamElem[1].pNode->value, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) {
|
int32_t code = getTickPerSecond(&pParamElem[1].pNode->value, precision, (char*) &tickPerSec, pMsgBuf);
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
}
|
return code;
|
||||||
|
|
||||||
if (info.precision == TSDB_TIME_PRECISION_MILLI) {
|
|
||||||
tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MICRO);
|
|
||||||
} else if (info.precision == TSDB_TIME_PRECISION_MICRO) {
|
|
||||||
tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MILLI);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tickPerSec <= 0 || tickPerSec < TSDB_TICK_PER_SECOND(info.precision)) {
|
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addExprInfoParam(&pExpr->base, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
addExprInfoParam(&pExpr->base, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
||||||
|
@ -1253,10 +1243,10 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
||||||
|
|
||||||
numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
|
numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
|
||||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, numOfOutput, pExpr, pSchema, finalResult);
|
doAddResColumnOrSourceColumn(pQueryInfo, &index, numOfOutput, pExpr, &columnSchema, finalResult);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1273,7 +1263,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taosArrayGetSize(pParamList) > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) {
|
if (taosArrayGetSize(pParamList) > 1 && (pItem->aliasName != NULL)) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg8);
|
return buildInvalidOperationMsg(pMsgBuf, msg8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,8 +1292,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
SToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
SToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
||||||
setResultColName(name, pItem, &t, &pItem->pNode->exprToken, true);
|
setResultColName(name, pItem, &t, &pItem->pNode->exprToken, true);
|
||||||
|
|
||||||
if (setExprInfoForFunctions(pQueryInfo, &pSchema[j], functionId, name, colIndex++, &index,
|
if (setMultipleExprsInSelect(pQueryInfo, &pSchema[j], functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) {
|
||||||
finalResult, pMsgBuf) != 0) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1326,13 +1315,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1;
|
bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1;
|
||||||
setResultColName(name, pItem, &pParamElem->pNode->columnName, &pItem->pNode->exprToken, multiColOutput);
|
setResultColName(name, pItem, &pParamElem->pNode->columnName, &pItem->pNode->exprToken, multiColOutput);
|
||||||
|
|
||||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) {
|
if (setMultipleExprsInSelect(pQueryInfo, pSchema, functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // select * from xxx
|
} else { // select function(*) from xxx
|
||||||
int32_t numOfFields = 0;
|
int32_t numOfFields = 0;
|
||||||
|
|
||||||
// multicolumn selection does not support alias name
|
// multicolumn selection does not support alias name
|
||||||
|
@ -1345,14 +1334,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
|
SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
||||||
SColumnIndex index = {.tableIndex = j, .columnIndex = i};
|
SColumnIndex index = {.tableIndex = j, .columnIndex = i, .type = TSDB_COL_NORMAL};
|
||||||
|
|
||||||
char name[TSDB_COL_NAME_LEN] = {0};
|
char name[TSDB_COL_NAME_LEN] = {0};
|
||||||
SToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
SToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
||||||
setResultColName(name, pItem, &t, &pItem->pNode->exprToken, true);
|
setResultColName(name, pItem, &t, &pItem->pNode->Expr.operand, true);
|
||||||
|
|
||||||
if (setExprInfoForFunctions(pQueryInfo, &pSchema[index.columnIndex], functionId, name, colIndex, &index,
|
if (setMultipleExprsInSelect(pQueryInfo, &pSchema[index.columnIndex], functionId, name, colIndex, &index, finalResult, pMsgBuf) != 0) {
|
||||||
finalResult, pMsgBuf) != 0) {
|
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
colIndex++;
|
colIndex++;
|
||||||
|
@ -1428,10 +1416,9 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
*/
|
*/
|
||||||
colIndex += 1; // the first column is ts
|
colIndex += 1; // the first column is ts
|
||||||
|
|
||||||
SSchema s = {0};
|
SSchema s = createSchema(resultType, resultSize, getNewResColId(), "");
|
||||||
setSchemaVal(&s, resultType, resultSize, getNewResColId(), "");
|
|
||||||
|
|
||||||
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, interResult);
|
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, interResult);
|
||||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1443,26 +1430,17 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the first column ts for top/bottom query
|
// set the first column ts for top/bottom query
|
||||||
SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_COL_NORMAL};
|
setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, colIndex, index.tableIndex);
|
||||||
|
|
||||||
SSchema s = {0};
|
|
||||||
setSchemaVal(&s, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts");
|
|
||||||
|
|
||||||
pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS, &index1, &s, 0);
|
|
||||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
|
||||||
|
|
||||||
addResColumnInfo(pQueryInfo, colIndex, &index1, &pExpr->base.resSchema, pExpr);
|
|
||||||
|
|
||||||
colIndex += 1; // the first column is ts
|
colIndex += 1; // the first column is ts
|
||||||
|
|
||||||
setSchemaVal(&s, resultType, resultSize, getNewResColId(), "");
|
SSchema s = createSchema(resultType, resultSize, getNewResColId(), "");
|
||||||
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, resultSize);
|
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, resultSize);
|
||||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||||
|
|
||||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t));
|
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
||||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, pSchema, finalResult);
|
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, pSchema, finalResult);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1533,8 +1511,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
s.colId = getNewResColId();
|
s.colId = getNewResColId();
|
||||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
|
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
|
||||||
|
|
||||||
addExprInSelect(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s);
|
doAddOneExprInfo(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s, s.name);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,7 +1521,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SColumnIndex index = {.tableIndex = 0, .columnIndex = 0, .type = TSDB_COL_TAG};
|
SColumnIndex index = {.tableIndex = 0, .columnIndex = 0, .type = TSDB_COL_NORMAL};
|
||||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
|
|
||||||
int32_t inter = 0;
|
int32_t inter = 0;
|
||||||
|
@ -1553,13 +1530,15 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
|
|
||||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, 0);
|
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, 0);
|
||||||
|
|
||||||
SSchema s = {0};
|
SSchema s = createSchema(TSDB_DATA_TYPE_BINARY, bytes, getNewResColId(), "block_dist");
|
||||||
setSchemaVal(&s, TSDB_DATA_TYPE_BINARY, bytes, getNewResColId(), "block_dist");
|
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, 0);
|
||||||
SExprInfo* pExpr = addExprInSelect(pQueryInfo, 0, FUNCTION_BLKINFO, &index, &s);
|
addExprInfo(pQueryInfo, 0, pExpr);
|
||||||
|
|
||||||
pExpr->base.numOfParams = 1;
|
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN);
|
||||||
pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize;
|
|
||||||
pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT;
|
int64_t rowSize = pTableMetaInfo->pTableMeta->tableInfo.rowSize;
|
||||||
|
addExprInfoParam(&pExpr->base, (char*) &rowSize, TSDB_DATA_TYPE_BIGINT, 8);
|
||||||
|
doAddResColumnOrSourceColumn(pQueryInfo, &index, 0, pExpr, &s, true);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1596,14 +1575,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
int16_t bytes = 0;
|
int16_t bytes = 0;
|
||||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false/*, pUdfInfo*/);
|
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false/*, pUdfInfo*/);
|
||||||
|
|
||||||
SSchema s = {0};
|
SSchema s = createSchema(resType, bytes, getNewResColId(), "");
|
||||||
setSchemaVal(&s, resType, bytes, getNewResColId(), "");
|
SExprInfo *pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, inter);
|
||||||
SExprInfo *pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, inter);
|
|
||||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||||
|
|
||||||
getColumnName(pItem, s.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
setTokenAndResColumnName(pItem, s.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
||||||
|
|
||||||
setSchemaVal(&s, resType, bytes, pExpr->base.colInfo.colId, "");
|
s = createSchema(resType, bytes, pExpr->base.colInfo.colId, "");
|
||||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, &s, finalResult);
|
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, &s, finalResult);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1613,34 +1591,25 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
||||||
}
|
}
|
||||||
|
|
||||||
SExprInfo* doAddProjectCol(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, SColumnIndex* pColIndex, const char* aliasName, int32_t colId) {
|
SExprInfo* doAddProjectCol(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, SColumnIndex* pColIndex, const char* aliasName, int32_t colId) {
|
||||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
|
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, pColIndex->tableIndex)->pTableMeta;
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
|
||||||
|
|
||||||
int32_t numOfCols = getNumOfColumns(pTableMeta);
|
|
||||||
SSchema* pSchema = getOneColumnSchema(pTableMeta, pColIndex->columnIndex);
|
SSchema* pSchema = getOneColumnSchema(pTableMeta, pColIndex->columnIndex);
|
||||||
|
|
||||||
SColumnIndex index = *pColIndex;
|
SColumnIndex index = *pColIndex;
|
||||||
int16_t functionId = TSDB_COL_IS_TAG(index.type)? FUNCTION_TAGPRJ : FUNCTION_PRJ;
|
|
||||||
|
|
||||||
if (functionId == FUNCTION_TAGPRJ) {
|
int16_t functionId = 0;
|
||||||
|
if (TSDB_COL_IS_TAG(index.type)) {
|
||||||
|
int32_t numOfCols = getNumOfColumns(pTableMeta);
|
||||||
index.columnIndex = pColIndex->columnIndex - numOfCols;
|
index.columnIndex = pColIndex->columnIndex - numOfCols;
|
||||||
columnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->uid, pSchema);
|
functionId = FUNCTION_TAGPRJ;
|
||||||
} else {
|
} else {
|
||||||
index.columnIndex = pColIndex->columnIndex;
|
index.columnIndex = pColIndex->columnIndex;
|
||||||
|
functionId = FUNCTION_PRJ;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema s = {0};
|
const char* name = (aliasName == NULL)? pSchema->name:aliasName;
|
||||||
setSchemaVal(&s, pSchema->type, pSchema->bytes, colId, pSchema->name);
|
SSchema s = createSchema(pSchema->type, pSchema->bytes, colId, name);
|
||||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, 0);
|
|
||||||
|
|
||||||
if (aliasName == NULL) {
|
return doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, &index, &s, pSchema->name);
|
||||||
tstrncpy(pExpr->base.resSchema.name, pSchema->name, sizeof(pExpr->base.resSchema.name));
|
|
||||||
} else {
|
|
||||||
tstrncpy(pExpr->base.resSchema.name, aliasName, TSDB_COL_NAME_LEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
addExprInfo(pQueryInfo, outputColIndex, pExpr);
|
|
||||||
addResColumnInfo(pQueryInfo, outputColIndex, pColIndex, pSchema, pExpr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t doAddProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
|
static int32_t doAddProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
|
||||||
|
@ -1699,9 +1668,12 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
||||||
const char* msg2 = "invalid column name";
|
const char* msg2 = "invalid column name";
|
||||||
const char* msg3 = "tbname not allowed in outer query";
|
const char* msg3 = "tbname not allowed in outer query";
|
||||||
|
|
||||||
|
if (checkForAliasName(pMsgBuf, pItem->aliasName) != TSDB_CODE_SUCCESS) {
|
||||||
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo);
|
int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo);
|
||||||
int32_t tokenId = pItem->pNode->tokenId;
|
int32_t tokenId = pItem->pNode->tokenId;
|
||||||
|
|
||||||
if (tokenId == TK_ALL) { // project on all fields
|
if (tokenId == TK_ALL) { // project on all fields
|
||||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);
|
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY);
|
||||||
|
|
||||||
|
@ -1729,7 +1701,10 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
||||||
} else if (tokenId == TK_STRING || tokenId == TK_INTEGER || tokenId == TK_FLOAT) { // simple column projection query
|
} else if (tokenId == TK_STRING || tokenId == TK_INTEGER || tokenId == TK_FLOAT) { // simple column projection query
|
||||||
SColumnIndex index = createConstantColumnIndex(&pQueryInfo->udColumnId);
|
SColumnIndex index = createConstantColumnIndex(&pQueryInfo->udColumnId);
|
||||||
SSchema colSchema = createConstantColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName);
|
SSchema colSchema = createConstantColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName);
|
||||||
SExprInfo* pExpr = addExprInSelect(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema);
|
|
||||||
|
char rawName[TSDB_COL_NAME_LEN] = {0};
|
||||||
|
tstrncpy(rawName, pItem->pNode->exprToken.z, MIN(TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN));
|
||||||
|
SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema, rawName);
|
||||||
|
|
||||||
// NOTE: the first parameter is reserved for the tag column id during join query process.
|
// NOTE: the first parameter is reserved for the tag column id during join query process.
|
||||||
pExpr->base.numOfParams = 2;
|
pExpr->base.numOfParams = 2;
|
||||||
|
@ -1741,6 +1716,9 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
SSchema colSchema = {0};
|
||||||
|
int32_t functionId = 0;
|
||||||
|
|
||||||
if (outerQuery) { // todo??
|
if (outerQuery) { // todo??
|
||||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
|
|
||||||
|
@ -1760,24 +1738,17 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema colSchema = pSchema[index.columnIndex];
|
colSchema = pSchema[index.columnIndex];
|
||||||
colSchema.colId = getNewResColId();
|
functionId = FUNCTION_PRJ;
|
||||||
|
|
||||||
char name[TSDB_COL_NAME_LEN] = {0};
|
|
||||||
getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1);
|
|
||||||
tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN);
|
|
||||||
|
|
||||||
addExprInSelect(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema);
|
|
||||||
} else {
|
} else {
|
||||||
SSchema colSchema = *getTbnameColumnSchema();
|
colSchema = *getTbnameColumnSchema();
|
||||||
char name[TSDB_COL_NAME_LEN] = {0};
|
functionId = FUNCTION_TAGPRJ;
|
||||||
getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1);
|
}
|
||||||
|
|
||||||
tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN);
|
|
||||||
|
|
||||||
colSchema.colId = getNewResColId();
|
colSchema.colId = getNewResColId();
|
||||||
addExprInSelect(pQueryInfo, startPos, FUNCTION_TAGPRJ, &index, &colSchema);
|
char rawName[TSDB_COL_NAME_LEN] = {0};
|
||||||
}
|
setTokenAndResColumnName(pItem, colSchema.name, rawName, sizeof(colSchema.name) - 1);
|
||||||
|
doAddOneExprInfo(pQueryInfo, startPos, functionId, &index, &colSchema, rawName);
|
||||||
} else {
|
} else {
|
||||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
if (TSDB_COL_IS_TAG(index.type) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
if (TSDB_COL_IS_TAG(index.type) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
||||||
|
@ -1785,7 +1756,6 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
||||||
}
|
}
|
||||||
|
|
||||||
doAddProjectCol(pQueryInfo, startPos, &index, pItem->aliasName, getNewResColId());
|
doAddProjectCol(pQueryInfo, startPos, &index, pItem->aliasName, getNewResColId());
|
||||||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the primary timestamp column even though it is not required by user
|
// add the primary timestamp column even though it is not required by user
|
||||||
|
@ -1880,7 +1850,7 @@ static int32_t validateExprLeafNode(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo,
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf) {
|
int32_t validateComplexExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf) {
|
||||||
if (pExpr == NULL) {
|
if (pExpr == NULL) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1890,7 +1860,7 @@ static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQuery
|
||||||
uint64_t uidRight = 0;
|
uint64_t uidRight = 0;
|
||||||
|
|
||||||
if (pLeft->type == SQL_NODE_EXPR) {
|
if (pLeft->type == SQL_NODE_EXPR) {
|
||||||
int32_t ret = validateArithmeticSqlExpr(pLeft, pQueryInfo, pColList, type, pMsgBuf);
|
int32_t ret = validateComplexExpr(pLeft, pQueryInfo, pColList, type, pMsgBuf);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1903,7 +1873,7 @@ static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQuery
|
||||||
|
|
||||||
tSqlExpr* pRight = pExpr->pRight;
|
tSqlExpr* pRight = pExpr->pRight;
|
||||||
if (pRight->type == SQL_NODE_EXPR) {
|
if (pRight->type == SQL_NODE_EXPR) {
|
||||||
int32_t ret = validateArithmeticSqlExpr(pRight, pQueryInfo, pColList, type, pMsgBuf);
|
int32_t ret = validateComplexExpr(pRight, pQueryInfo, pColList, type, pMsgBuf);
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1995,7 +1965,6 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
|
||||||
|
|
||||||
pQueryInfo->curTableIdx = index.tableIndex;
|
pQueryInfo->curTableIdx = index.tableIndex;
|
||||||
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
|
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
|
||||||
int32_t numOfColumns = getNumOfColumns(pTableMeta);
|
|
||||||
|
|
||||||
*pExpr = calloc(1, sizeof(tExprNode));
|
*pExpr = calloc(1, sizeof(tExprNode));
|
||||||
(*pExpr)->nodeType = TEXPR_COL_NODE;
|
(*pExpr)->nodeType = TEXPR_COL_NODE;
|
||||||
|
@ -2009,7 +1978,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
|
||||||
tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
|
tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name));
|
||||||
colIndex.colId = pSchema->colId;
|
colIndex.colId = pSchema->colId;
|
||||||
colIndex.colIndex = index.columnIndex;
|
colIndex.colIndex = index.columnIndex;
|
||||||
colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0;
|
colIndex.flag = index.type;
|
||||||
|
|
||||||
taosArrayPush(pCols, &colIndex);
|
taosArrayPush(pCols, &colIndex);
|
||||||
}
|
}
|
||||||
|
@ -2058,9 +2027,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
|
||||||
(*pExpr)->_node.pRight = pRight;
|
(*pExpr)->_node.pRight = pRight;
|
||||||
|
|
||||||
SToken t = {.type = pSqlExpr->tokenId};
|
SToken t = {.type = pSqlExpr->tokenId};
|
||||||
#if 0
|
|
||||||
(*pExpr)->_node.optr = convertRelationalOperator(&t);
|
(*pExpr)->_node.optr = convertRelationalOperator(&t);
|
||||||
#endif
|
|
||||||
|
|
||||||
assert((*pExpr)->_node.optr != 0);
|
assert((*pExpr)->_node.optr != 0);
|
||||||
|
|
||||||
|
@ -2068,9 +2035,9 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
|
||||||
if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
|
if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
|
||||||
if (pRight->nodeType == TEXPR_VALUE_NODE) {
|
if (pRight->nodeType == TEXPR_VALUE_NODE) {
|
||||||
if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) {
|
if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return buildInvalidOperationMsg(pMsgBuf, "invalid expr (divide by 0)");
|
||||||
} else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->d == 0) {
|
} else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->d == 0) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return buildInvalidOperationMsg(pMsgBuf, "invalid expr (divide by 0)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2079,7 +2046,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
|
||||||
if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
|
if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
|
||||||
if (pRight != NULL && pRight->nodeType == TEXPR_VALUE_NODE) {
|
if (pRight != NULL && pRight->nodeType == TEXPR_VALUE_NODE) {
|
||||||
if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL) {
|
if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return buildInvalidOperationMsg(pMsgBuf, "invalid operator for bool");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2088,33 +2055,41 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem, SMsgBuf* pMsgBuf) {
|
static int32_t multiColumnListInsert(SQueryStmtInfo* pQueryInfo, SArray* pColumnList, SMsgBuf* pMsgBuf) {
|
||||||
|
const char* msg3 = "tag columns can not be used in arithmetic expression";
|
||||||
|
|
||||||
|
SColumnIndex* p1 = taosArrayGet(pColumnList, 0);
|
||||||
|
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, p1->tableIndex)->pTableMeta;
|
||||||
|
|
||||||
|
size_t numOfNode = taosArrayGetSize(pColumnList);
|
||||||
|
for(int32_t k = 0; k < numOfNode; ++k) {
|
||||||
|
SColumnIndex* pIndex = taosArrayGet(pColumnList, k);
|
||||||
|
if (TSDB_COL_IS_TAG(pIndex->type)) {
|
||||||
|
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSchema* ps = getOneColumnSchema(pTableMeta, pIndex->columnIndex);
|
||||||
|
columnListInsert(pQueryInfo->colList, pIndex->columnIndex, pTableMeta->uid, ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
insertPrimaryTsColumn(pQueryInfo->colList, pTableMeta->uid);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem, SMsgBuf* pMsgBuf) {
|
||||||
const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
|
const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
|
||||||
const char* msg2 = "invalid arithmetic expression in select clause";
|
const char* msg2 = "invalid arithmetic expression in select clause";
|
||||||
const char* msg3 = "tag columns can not be used in arithmetic expression";
|
const char* msg3 = "tag columns can not be used in arithmetic expression";
|
||||||
const char* msg4 = "columns from different table mixed up in arithmetic expression";
|
|
||||||
|
|
||||||
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||||
SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex));
|
SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex));
|
||||||
if (validateArithmeticSqlExpr(pItem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
if (validateComplexExpr(pItem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tableIndex = ((SColumnIndex*)(taosArrayGet(pColumnList, 0)))->tableIndex;
|
|
||||||
if (arithmeticType == NORMAL_ARITHMETIC) {
|
if (arithmeticType == NORMAL_ARITHMETIC) {
|
||||||
pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
|
||||||
|
|
||||||
// expr string is set as the parameter of function
|
// expr string is set as the parameter of function
|
||||||
SColumnIndex index = {.tableIndex = tableIndex, .type = TSDB_COL_NORMAL};
|
SSchema s = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
|
||||||
|
|
||||||
SSchema s = {0};
|
|
||||||
setSchemaVal(&s, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
|
|
||||||
|
|
||||||
char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z;
|
|
||||||
size_t len = MIN(sizeof(s.name), pItem->pNode->exprToken.n + 1);
|
|
||||||
tstrncpy(s.name, name, len);
|
|
||||||
|
|
||||||
SExprInfo* pExpr = createExprInfo(NULL, FUNCTION_ARITHM, &index, &s, sizeof(double));
|
|
||||||
|
|
||||||
tExprNode* pNode = NULL;
|
tExprNode* pNode = NULL;
|
||||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||||
|
@ -2125,16 +2100,16 @@ static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprInde
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for if there is a tag in the arithmetic express
|
SExprInfo* pExpr = createBinaryExprInfo(pNode, &s);
|
||||||
size_t numOfNode = taosArrayGetSize(colList);
|
addExprInfo(pQueryInfo, exprIndex, pExpr);
|
||||||
for(int32_t k = 0; k < numOfNode; ++k) {
|
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN);
|
||||||
SColIndex* pIndex = taosArrayGet(colList, k);
|
|
||||||
if (TSDB_COL_IS_TAG(pIndex->flag)) {
|
|
||||||
tExprTreeDestroy(pNode, NULL);
|
|
||||||
taosArrayDestroy(colList);
|
|
||||||
|
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
// check for if there is a tag in the arithmetic express
|
||||||
}
|
int32_t code = multiColumnListInsert(pQueryInfo, pColumnList, pMsgBuf);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
taosArrayDestroy(colList);
|
||||||
|
tExprTreeDestroy(pNode, NULL);
|
||||||
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
SBufferWriter bw = tbufInitWriter(NULL, false);
|
SBufferWriter bw = tbufInitWriter(NULL, false);
|
||||||
|
@ -2147,16 +2122,13 @@ static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprInde
|
||||||
// TODO: other error handling
|
// TODO: other error handling
|
||||||
// } END_TRY
|
// } END_TRY
|
||||||
|
|
||||||
len = tbufTell(&bw);
|
int32_t len = tbufTell(&bw);
|
||||||
char* c = tbufGetData(&bw, false);
|
char* c = tbufGetData(&bw, false);
|
||||||
|
|
||||||
// set the serialized binary string as the parameter of arithmetic expression
|
// set the serialized binary string as the parameter of arithmetic expression
|
||||||
SColumnIndex* index1 = taosArrayGet(pColumnList, 0);
|
SColumnIndex* index1 = taosArrayGet(pColumnList, 0);
|
||||||
addExprInfoParam(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
|
addExprInfoParam(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len);
|
||||||
addResColumnInfo(pQueryInfo, exprIndex, index1, &pExpr->base.resSchema, pExpr);
|
addResColumnInfo(pQueryInfo, exprIndex, &pExpr->base.resSchema, pExpr);
|
||||||
|
|
||||||
// add ts column
|
|
||||||
insertPrimaryTsColumn(pQueryInfo->colList, pExpr->base.uid);
|
|
||||||
|
|
||||||
tbufCloseWriter(&bw);
|
tbufCloseWriter(&bw);
|
||||||
taosArrayDestroy(colList);
|
taosArrayDestroy(colList);
|
||||||
|
@ -2164,47 +2136,38 @@ static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprInde
|
||||||
} else {
|
} else {
|
||||||
SColumnIndex columnIndex = {0};
|
SColumnIndex columnIndex = {0};
|
||||||
|
|
||||||
char rawName[TSDB_COL_NAME_LEN] = {0};
|
SSchema s = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
|
||||||
char aliasName[TSDB_COL_NAME_LEN] = {0};
|
addResColumnInfo(pQueryInfo, exprIndex, &s, NULL);
|
||||||
getColumnName(pItem, aliasName, rawName, TSDB_COL_NAME_LEN);
|
|
||||||
|
|
||||||
SSchema s = {0};
|
tExprNode* pNode = NULL;
|
||||||
setSchemaVal(&s, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), aliasName);
|
int32_t ret = sqlExprToExprNode(&pNode, pItem->pNode, pQueryInfo, NULL, NULL, pMsgBuf);
|
||||||
|
|
||||||
addResColumnInfo(pQueryInfo, exprIndex, &columnIndex, &s, NULL);
|
|
||||||
|
|
||||||
int32_t slot = getNumOfFields(&pQueryInfo->fieldsInfo) - 1;
|
|
||||||
SInternalField* pInfo = getInternalField(&pQueryInfo->fieldsInfo, slot);
|
|
||||||
assert(pInfo->pExpr == NULL);
|
|
||||||
|
|
||||||
SExprInfo* pExpr = createExprInfo(NULL, FUNCTION_ARITHM, &columnIndex, &s, 0);
|
|
||||||
strncpy(pExpr->base.token, rawName, tListLen(pExpr->base.token));
|
|
||||||
|
|
||||||
pExpr->base.numOfParams = 1;
|
|
||||||
|
|
||||||
int32_t ret = sqlExprToExprNode(&pExpr->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExpr->base.uid), pMsgBuf);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
if (ret != TSDB_CODE_SUCCESS) {
|
||||||
tExprTreeDestroy(pExpr->pExpr, NULL);
|
tExprTreeDestroy(pNode, NULL);
|
||||||
return buildInvalidOperationMsg(pMsgBuf, "invalid expression in select clause");
|
return buildInvalidOperationMsg(pMsgBuf, "invalid expression in select clause");
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->pExpr = pExpr;
|
SExprInfo* pExpr = createBinaryExprInfo(pNode, &s);
|
||||||
|
addExprInfo(pQueryInfo, exprIndex, pExpr);
|
||||||
|
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN);
|
||||||
|
|
||||||
|
pExpr->base.numOfParams = 1;
|
||||||
|
|
||||||
SBufferWriter bw = tbufInitWriter(NULL, false);
|
SBufferWriter bw = tbufInitWriter(NULL, false);
|
||||||
|
|
||||||
// TRY(0) {
|
// TRY(0) {
|
||||||
exprTreeToBinary(&bw, pInfo->pExpr->pExpr);
|
exprTreeToBinary(&bw, pExpr->pExpr);
|
||||||
// } CATCH(code) {
|
// } CATCH(code) {
|
||||||
// tbufCloseWriter(&bw);
|
// tbufCloseWriter(&bw);
|
||||||
// UNUSED(code);
|
// UNUSED(code);
|
||||||
// TODO: other error handling
|
// TODO: other error handling
|
||||||
// } END_TRY
|
// } END_TRY
|
||||||
|
|
||||||
SSqlExpr* pSqlExpr = &pInfo->pExpr->base;
|
SSqlExpr* pSqlExpr = &pExpr->base;
|
||||||
pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw);
|
pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw);
|
||||||
pSqlExpr->param[0].pz = tbufGetData(&bw, true);
|
pSqlExpr->param[0].pz = tbufGetData(&bw, true);
|
||||||
pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY;
|
pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY;
|
||||||
|
|
||||||
|
tbufCloseWriter(&bw);
|
||||||
|
|
||||||
// tbufCloseWriter(&bw); // TODO there is a memory leak
|
// tbufCloseWriter(&bw); // TODO there is a memory leak
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2268,7 +2231,7 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
} else if (type == SQL_NODE_EXPR) {
|
} else if (type == SQL_NODE_EXPR) {
|
||||||
int32_t code = handleArithmeticExpr(pQueryInfo, i, pItem, pMsgBuf);
|
int32_t code = createComplexExpr(pQueryInfo, i, pItem, pMsgBuf);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2285,10 +2248,6 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
|
||||||
// size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
|
// size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
|
||||||
// if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
|
// if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
|
||||||
// addPrimaryTsColIntoResult(pQueryInfo, pCmd);
|
// addPrimaryTsColIntoResult(pQueryInfo, pCmd);
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) {
|
|
||||||
// return buildInvalidOperationMsg(pMsgBuf, msg2);
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
@ -2306,6 +2265,16 @@ int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf)
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t size = taosArrayGetSize(pNode->pSelNodeList);
|
||||||
|
for(int32_t i = 0; i < size; ++i) {
|
||||||
|
tSqlExprItem* pItem = taosArrayGet(pNode->pSelNodeList, i);
|
||||||
|
code = evaluateImpl(pItem->pNode, tsPrecision);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code = evaluateImpl(pNode->pSelNodeList, tsPrecision);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2782,6 +2751,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < len; ++i) {
|
||||||
|
SSqlNode* p = taosArrayGetP(pInfo->list, i);
|
||||||
|
validateSqlNode(p, pQueryInfo, &buf);
|
||||||
|
}
|
||||||
|
|
||||||
// convert the sqlnode into queryinfo
|
// convert the sqlnode into queryinfo
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ bool qIsInsertSql(const char* pStr, size_t length) {
|
||||||
int32_t index = 0;
|
int32_t index = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
SToken t0 = tStrGetToken(pStr, &index, false);
|
SToken t0 = tStrGetToken((char*) pStr, &index, false);
|
||||||
if (t0.type != TK_LP) {
|
if (t0.type != TK_LP) {
|
||||||
return t0.type == TK_INSERT || t0.type == TK_IMPORT;
|
return t0.type == TK_INSERT || t0.type == TK_IMPORT;
|
||||||
}
|
}
|
||||||
|
@ -120,17 +120,12 @@ int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgB
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tscDequoteAndTrimToken(t);
|
|
||||||
if (parserValidateIdToken(t) != TSDB_CODE_SUCCESS) {
|
if (parserValidateIdToken(t) != TSDB_CODE_SUCCESS) {
|
||||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
SName name = {0};
|
SName name = {0};
|
||||||
// int32_t code = tscSetTableFullName(&name, t, pSql);
|
strndequote(name.tname, t->z, t->n);
|
||||||
// if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
// return code;
|
|
||||||
// }
|
|
||||||
|
|
||||||
taosArrayPush(tableNameList, &name);
|
taosArrayPush(tableNameList, &name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +178,7 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
|
||||||
assert(t != NULL);
|
assert(t != NULL);
|
||||||
|
|
||||||
if (t->n >= TSDB_FUNC_NAME_LEN) {
|
if (t->n >= TSDB_FUNC_NAME_LEN) {
|
||||||
return parserSetSyntaxErrMsg(msg, msgBufLen, "too long function name", t->z);
|
return buildSyntaxErrMsg(msg, msgBufLen, "too long function name", t->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's assume that it is an UDF/UDAF, if it is not a built-in function.
|
// Let's assume that it is an UDF/UDAF, if it is not a built-in function.
|
||||||
|
@ -193,4 +188,6 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
}
|
}
|
|
@ -26,6 +26,11 @@ int32_t parserValidateIdToken(SToken* pToken) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// it is a token quoted with escape char '`'
|
||||||
|
if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
|
char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true);
|
||||||
if (sep == NULL) { // It is a single part token, not a complex type
|
if (sep == NULL) { // It is a single part token, not a complex type
|
||||||
if (isNumber(pToken)) {
|
if (isNumber(pToken)) {
|
||||||
|
@ -83,7 +88,7 @@ int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) {
|
||||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t parserSetSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr) {
|
int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr) {
|
||||||
const char* msgFormat1 = "syntax error near \'%s\'";
|
const char* msgFormat1 = "syntax error near \'%s\'";
|
||||||
const char* msgFormat2 = "syntax error near \'%s\' (%s)";
|
const char* msgFormat2 = "syntax error near \'%s\' (%s)";
|
||||||
const char* msgFormat3 = "%s";
|
const char* msgFormat3 = "%s";
|
||||||
|
@ -499,13 +504,14 @@ TAOS_FIELD createField(const SSchema* pSchema) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSchemaVal(SSchema* pSchema, uint8_t type, int16_t bytes, int16_t colId, const char* name){
|
SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name) {
|
||||||
assert(pSchema != NULL);
|
SSchema s = {0};
|
||||||
pSchema->type = type;
|
s.type = type;
|
||||||
pSchema->bytes = bytes;
|
s.bytes = bytes;
|
||||||
pSchema->colId = colId;
|
s.colId = colId;
|
||||||
|
|
||||||
tstrncpy(pSchema->name, name, tListLen(pSchema->name));
|
tstrncpy(s.name, name, tListLen(s.name));
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getNumOfFields(SFieldInfo* pFieldInfo) {
|
int32_t getNumOfFields(SFieldInfo* pFieldInfo) {
|
||||||
|
@ -1598,6 +1604,52 @@ int32_t getTagFilterSerializeLen(SQueryStmtInfo* pQueryInfo) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t convertRelationalOperator(SToken *pToken) {
|
||||||
|
switch (pToken->type) {
|
||||||
|
case TK_LT:
|
||||||
|
return TSDB_RELATION_LESS;
|
||||||
|
case TK_LE:
|
||||||
|
return TSDB_RELATION_LESS_EQUAL;
|
||||||
|
case TK_GT:
|
||||||
|
return TSDB_RELATION_GREATER;
|
||||||
|
case TK_GE:
|
||||||
|
return TSDB_RELATION_GREATER_EQUAL;
|
||||||
|
case TK_NE:
|
||||||
|
return TSDB_RELATION_NOT_EQUAL;
|
||||||
|
case TK_AND:
|
||||||
|
return TSDB_RELATION_AND;
|
||||||
|
case TK_OR:
|
||||||
|
return TSDB_RELATION_OR;
|
||||||
|
case TK_EQ:
|
||||||
|
return TSDB_RELATION_EQUAL;
|
||||||
|
case TK_PLUS:
|
||||||
|
return TSDB_BINARY_OP_ADD;
|
||||||
|
|
||||||
|
case TK_MINUS:
|
||||||
|
return TSDB_BINARY_OP_SUBTRACT;
|
||||||
|
case TK_STAR:
|
||||||
|
return TSDB_BINARY_OP_MULTIPLY;
|
||||||
|
case TK_SLASH:
|
||||||
|
case TK_DIVIDE:
|
||||||
|
return TSDB_BINARY_OP_DIVIDE;
|
||||||
|
case TK_REM:
|
||||||
|
return TSDB_BINARY_OP_REMAINDER;
|
||||||
|
case TK_LIKE:
|
||||||
|
return TSDB_RELATION_LIKE;
|
||||||
|
case TK_MATCH:
|
||||||
|
return TSDB_RELATION_MATCH;
|
||||||
|
case TK_NMATCH:
|
||||||
|
return TSDB_RELATION_NMATCH;
|
||||||
|
case TK_ISNULL:
|
||||||
|
return TSDB_RELATION_ISNULL;
|
||||||
|
case TK_NOTNULL:
|
||||||
|
return TSDB_RELATION_NOTNULL;
|
||||||
|
case TK_IN:
|
||||||
|
return TSDB_RELATION_IN;
|
||||||
|
default: { return 0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int32_t tscCreateQueryFromQueryInfo(SQueryStmtInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) {
|
int32_t tscCreateQueryFromQueryInfo(SQueryStmtInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) {
|
||||||
memset(pQueryAttr, 0, sizeof(SQueryAttr));
|
memset(pQueryAttr, 0, sizeof(SQueryAttr));
|
||||||
|
|
|
@ -55,11 +55,16 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
|
||||||
return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns);
|
return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema) {
|
static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) {
|
||||||
tExprNode* pColumnNode = calloc(1, sizeof(tExprNode));
|
|
||||||
|
if (pColumnNode == NULL) {
|
||||||
|
pColumnNode = calloc(1, sizeof(tExprNode));
|
||||||
pColumnNode->nodeType = TEXPR_COL_NODE;
|
pColumnNode->nodeType = TEXPR_COL_NODE;
|
||||||
pColumnNode->pSchema = calloc(1, sizeof(SSchema));
|
pColumnNode->pSchema = calloc(1, sizeof(SSchema));
|
||||||
memcpy(pColumnNode->pSchema, pSchema, sizeof(SSchema));
|
memcpy(pColumnNode->pSchema, pSchema, sizeof(SSchema));
|
||||||
|
} else {
|
||||||
|
assert(pSchema == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
tExprNode* pNode = calloc(1, sizeof(tExprNode));
|
tExprNode* pNode = calloc(1, sizeof(tExprNode));
|
||||||
pNode->nodeType = TEXPR_UNARYEXPR_NODE;
|
pNode->nodeType = TEXPR_UNARYEXPR_NODE;
|
||||||
|
@ -69,7 +74,20 @@ static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSche
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, SSchema* pResSchema, int16_t interSize) {
|
SExprInfo* createBinaryExprInfo(tExprNode* pNode, SSchema* pResSchema) {
|
||||||
|
assert(pNode != NULL && pResSchema != NULL);
|
||||||
|
|
||||||
|
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
|
||||||
|
if (pExpr == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pExpr->pExpr = pNode;
|
||||||
|
memcpy(&pExpr->base.resSchema, pResSchema, sizeof(SSchema));
|
||||||
|
return pExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize) {
|
||||||
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
|
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
|
||||||
if (pExpr == NULL) {
|
if (pExpr == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -77,29 +95,26 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC
|
||||||
|
|
||||||
SSqlExpr* p = &pExpr->base;
|
SSqlExpr* p = &pExpr->base;
|
||||||
|
|
||||||
// set the correct columnIndex index
|
if (pParamExpr != NULL) {
|
||||||
if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
pExpr->pExpr = createUnaryFunctionExprNode(functionId, NULL, pParamExpr);
|
||||||
|
} else if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
assert(pParamExpr == NULL);
|
||||||
|
|
||||||
SSchema* s = getTbnameColumnSchema();
|
SSchema* s = getTbnameColumnSchema();
|
||||||
p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
|
p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
|
||||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, s);
|
pExpr->pExpr = createUnaryFunctionExprNode(functionId, s, pParamExpr);
|
||||||
} else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) {
|
} else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX || functionId == FUNCTION_BLKINFO) {
|
||||||
|
assert(pParamExpr == NULL);
|
||||||
|
|
||||||
p->colInfo.colId = pColIndex->columnIndex;
|
p->colInfo.colId = pColIndex->columnIndex;
|
||||||
SSchema s = {.colId = pColIndex->columnIndex, .bytes = pResSchema->bytes, .type = pResSchema->type};
|
SSchema s = createSchema(pResSchema->type, pResSchema->bytes, pColIndex->columnIndex, pResSchema->name);
|
||||||
tstrncpy(s.name, pResSchema->name, TSDB_COL_NAME_LEN);
|
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s, pParamExpr);
|
||||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s);
|
|
||||||
} else if (functionId == FUNCTION_BLKINFO) {
|
|
||||||
p->colInfo.colId = pColIndex->columnIndex;
|
|
||||||
SSchema s = {.colId = pColIndex->columnIndex, .bytes = pResSchema->bytes, .type = pResSchema->type};
|
|
||||||
tstrncpy(s.name, pResSchema->name, TSDB_COL_NAME_LEN);
|
|
||||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s);
|
|
||||||
// p->colBytes = TSDB_MAX_BINARY_LEN;
|
|
||||||
// p->colType = TSDB_DATA_TYPE_BINARY;
|
|
||||||
} else {
|
} else {
|
||||||
int32_t len = tListLen(p->colInfo.name);
|
int32_t len = tListLen(p->colInfo.name);
|
||||||
if (TSDB_COL_IS_TAG(pColIndex->type)) {
|
if (TSDB_COL_IS_TAG(pColIndex->type)) {
|
||||||
SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
|
SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||||
p->colInfo.colId = pSchema[pColIndex->columnIndex].colId;
|
p->colInfo.colId = pSchema[pColIndex->columnIndex].colId;
|
||||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex]);
|
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex], pParamExpr);
|
||||||
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name);
|
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name);
|
||||||
} else if (pTableMetaInfo->pTableMeta != NULL) {
|
} else if (pTableMetaInfo->pTableMeta != NULL) {
|
||||||
// in handling select database/version/server_status(), the pTableMeta is NULL
|
// in handling select database/version/server_status(), the pTableMeta is NULL
|
||||||
|
@ -107,7 +122,7 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC
|
||||||
p->colInfo.colId = pSchema->colId;
|
p->colInfo.colId = pSchema->colId;
|
||||||
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name);
|
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name);
|
||||||
|
|
||||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema);
|
pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema, pParamExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,367 @@
|
||||||
* 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 <gtest/gtest.h>
|
||||||
|
#include <iostream>
|
||||||
|
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
|
#include "astGenerator.h"
|
||||||
|
#include "parserInt.h"
|
||||||
|
#include "taos.h"
|
||||||
|
#include "tdef.h"
|
||||||
|
#include "tvariant.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) {
|
||||||
|
p->colId = colId;
|
||||||
|
p->bytes = bytes;
|
||||||
|
p->type = type;
|
||||||
|
strcpy(p->name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
|
||||||
|
pQueryInfo->numOfTables = 1;
|
||||||
|
|
||||||
|
pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES);
|
||||||
|
STableMetaInfo* pTableMetaInfo = (STableMetaInfo*)calloc(1, sizeof(STableMetaInfo));
|
||||||
|
pQueryInfo->pTableMetaInfo[0] = pTableMetaInfo;
|
||||||
|
|
||||||
|
SName* name = (SName*)taosArrayGet(req->pTableName, 0);
|
||||||
|
|
||||||
|
memcpy(&pTableMetaInfo->name, taosArrayGet(req->pTableName, 0), sizeof(SName));
|
||||||
|
pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 4 * sizeof(SSchema));
|
||||||
|
strcpy(pTableMetaInfo->aliasName, name->tname);
|
||||||
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
pTableMeta->tableType = TSDB_NORMAL_TABLE;
|
||||||
|
pTableMeta->tableInfo.numOfColumns = 4;
|
||||||
|
pTableMeta->tableInfo.rowSize = 28;
|
||||||
|
pTableMeta->uid = 110;
|
||||||
|
|
||||||
|
pTableMetaInfo->tagColList = (SArray*) taosArrayInit(4, POINTER_BYTES);
|
||||||
|
|
||||||
|
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
|
||||||
|
setSchema(&pSchema[0], TSDB_DATA_TYPE_TIMESTAMP, 8, "ts", 0);
|
||||||
|
setSchema(&pSchema[1], TSDB_DATA_TYPE_INT, 4, "a", 1);
|
||||||
|
setSchema(&pSchema[2], TSDB_DATA_TYPE_DOUBLE, 8, "b", 2);
|
||||||
|
setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, validateAST_test) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 110);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
|
||||||
|
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||||
|
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "a");
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||||
|
|
||||||
|
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||||
|
ASSERT_EQ(p2->base.uid, 0);
|
||||||
|
ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
|
||||||
|
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||||
|
ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
|
||||||
|
|
||||||
|
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
|
||||||
|
// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||||
|
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, function_Test) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 110);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)");
|
||||||
|
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||||
|
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||||
|
ASSERT_EQ(p1->base.interBytes, 8);
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, function_Test2) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 110);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc");
|
||||||
|
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||||
|
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||||
|
ASSERT_EQ(p1->base.interBytes, 8);
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, function_Test3) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 4);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 110);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)");
|
||||||
|
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||||
|
ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "first(ts)");
|
||||||
|
ASSERT_EQ(p1->base.interBytes, 24);
|
||||||
|
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, function_Test4) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 110);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||||
|
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||||
|
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "_block_dist()");
|
||||||
|
ASSERT_EQ(p1->base.interBytes, 0);
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, function_Test5) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 0);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||||
|
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||||
|
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)");
|
||||||
|
ASSERT_EQ(p1->base.interBytes, 0);
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(testCase, function_Test6) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1 from `t.1abc`");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMsgBuf buf;
|
||||||
|
buf.len = 128;
|
||||||
|
buf.buf = msg;
|
||||||
|
|
||||||
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||||
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
|
||||||
|
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||||
|
initQueryInfo(pQueryInfo);
|
||||||
|
setTableMetaInfo(pQueryInfo, &req);
|
||||||
|
|
||||||
|
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||||
|
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
|
||||||
|
SArray* pExprList = pQueryInfo->exprList;
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||||
|
|
||||||
|
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||||
|
ASSERT_EQ(p1->base.uid, 110);
|
||||||
|
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||||
|
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||||
|
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||||
|
ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)");
|
||||||
|
ASSERT_EQ(p1->base.interBytes, 16);
|
||||||
|
|
||||||
|
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||||
|
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
|
@ -89,6 +88,9 @@ TEST(testCase, validateToken_test) {
|
||||||
char t01[] = "abc";
|
char t01[] = "abc";
|
||||||
EXPECT_EQ(testValidateName(t01), TSDB_CODE_SUCCESS);
|
EXPECT_EQ(testValidateName(t01), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
|
char t110[] = "`1233abc.911`";
|
||||||
|
EXPECT_EQ(testValidateName(t110), TSDB_CODE_SUCCESS);
|
||||||
|
|
||||||
char t02[] = "'abc'";
|
char t02[] = "'abc'";
|
||||||
EXPECT_EQ(testValidateName(t02), TSDB_CODE_TSC_INVALID_OPERATION);
|
EXPECT_EQ(testValidateName(t02), TSDB_CODE_TSC_INVALID_OPERATION);
|
||||||
|
|
||||||
|
@ -689,7 +691,7 @@ TEST(testCase, generateAST_test) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(testCase, evaluateAST_test) {
|
TEST(testCase, evaluateAST_test) {
|
||||||
SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and col < 20 + 99");
|
SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||||
ASSERT_EQ(info1.valid, true);
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
char msg[128] = {0};
|
char msg[128] = {0};
|
||||||
|
@ -700,6 +702,16 @@ TEST(testCase, evaluateAST_test) {
|
||||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
|
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
|
||||||
ASSERT_EQ(code, 0);
|
ASSERT_EQ(code, 0);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(testCase, extractMeta_test) {
|
||||||
|
SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||||
|
ASSERT_EQ(info1.valid, true);
|
||||||
|
|
||||||
|
char msg[128] = {0};
|
||||||
|
SMetaReq req = {0};
|
||||||
|
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||||
|
ASSERT_EQ(ret, 0);
|
||||||
|
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ int32_t strdequote(char *z) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t quote = z[0];
|
int32_t quote = z[0];
|
||||||
if (quote != '\'' && quote != '"') {
|
if (quote != '\'' && quote != '"' && quote != '`') {
|
||||||
return (int32_t)strlen(z);
|
return (int32_t)strlen(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,34 @@ int32_t strRmquote(char *z, int32_t len){
|
||||||
return len - 2 - cnt;
|
return len - 2 - cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t strndequote(char *dst, const char* z, int32_t len) {
|
||||||
|
assert(dst != NULL);
|
||||||
|
if (z == NULL || len == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t quote = z[0];
|
||||||
|
int32_t i = 1, j = 0;
|
||||||
|
|
||||||
|
while (z[i] != 0) {
|
||||||
|
if (z[i] == quote) {
|
||||||
|
if (z[i + 1] == quote) {
|
||||||
|
dst[j++] = (char) quote;
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
dst[j++] = 0;
|
||||||
|
return (j - 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dst[j++] = z[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return j + 1; // only one quote, do nothing
|
||||||
|
}
|
||||||
|
|
||||||
size_t strtrim(char *z) {
|
size_t strtrim(char *z) {
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
int32_t j = 0;
|
int32_t j = 0;
|
||||||
|
|
Loading…
Reference in New Issue