ソースを参照

several bugfixes and refactor for new features (#1212)

* fix(infra): print out stack trace for catched panic

Signed-off-by: Jiyong Huang <huangjy@emqx.io>

* refactor(cast): remove unused dependency

Signed-off-by: Jiyong Huang <huangjy@emqx.io>

* fix(func): object_construct to ignore null value

Signed-off-by: Jiyong Huang <huangjy@emqx.io>
ngjaying 3 年 前
コミット
4027c36620

+ 7 - 7
docs/en_US/sqls/built-in_functions.md

@@ -126,13 +126,13 @@ Examples:
  
  
 ## Conversion Functions
 ## Conversion Functions
 
 
-| Function         | Example                          | Description                                                                                                                                                                                                                                                           |
-|------------------|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| cast             | cast(col,  "bigint")             | Converts a value from one data type to another. The supported types includes: bigint, float, string, boolean and datetime.                                                                                                                                            |
-| chr              | chr(col1)                        | Returns the ASCII character that corresponds to the given Int argument                                                                                                                                                                                                |
-| encode           | encode(col1, "base64")           | Use the encode function to encode the payload, which potentially might be non-JSON data, into its string representation based on the encoding scheme. Currently, only "base64" encoding type is supported.                                                            |
-| trunc            | trunc(dec, int)                  | Truncates the first argument to the number of Decimal places specified by the second argument. If the second argument is less than zero, it is set to zero. If the second argument is greater than 34, it is set to 34. Trailing zeroes are stripped from the result. |
-| object_construct | object_construct(key1, col, ...) | Return a struct type object/map constructed by the arguments. The arguments are series of key value pairs, thus the arguments count must be an odd number. The key must a string and the value can be of any type.                                                    |
+| Function         | Example                          | Description                                                                                                                                                                                                                                                                                       |
+|------------------|----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| cast             | cast(col,  "bigint")             | Converts a value from one data type to another. The supported types includes: bigint, float, string, boolean and datetime.                                                                                                                                                                        |
+| chr              | chr(col1)                        | Returns the ASCII character that corresponds to the given Int argument                                                                                                                                                                                                                            |
+| encode           | encode(col1, "base64")           | Use the encode function to encode the payload, which potentially might be non-JSON data, into its string representation based on the encoding scheme. Currently, only "base64" encoding type is supported.                                                                                        |
+| trunc            | trunc(dec, int)                  | Truncates the first argument to the number of Decimal places specified by the second argument. If the second argument is less than zero, it is set to zero. If the second argument is greater than 34, it is set to 34. Trailing zeroes are stripped from the result.                             |
+| object_construct | object_construct(key1, col, ...) | Return a struct type object/map constructed by the arguments. The arguments are series of key value pairs, thus the arguments count must be an odd number. The key must a string and the value can be of any type. If the value is null, the key/value pair will not present in the final object. |
 
 
 ### Cast to datetime
 ### Cast to datetime
 
 

+ 7 - 7
docs/zh_CN/sqls/built-in_functions.md

@@ -126,13 +126,13 @@ eKuiper 具有许多内置函数,可以对数据执行计算。
 
 
 ## 转换函数
 ## 转换函数
 
 
-| 函数               | 示例                               | 说明                                                                         |
-|------------------|----------------------------------|----------------------------------------------------------------------------|
-| cast             | cast(col,  "bigint")             | 将值从一种数据类型转换为另一种数据类型。 支持的类型包括:bigint,float,string,boolean 和 datetime。       |
-| chr              | chr(col1)                        | 返回与给定 Int 参数对应的 ASCII 字符                                                   |
-| encode           | encode(col1, "base64")           | 使用 encode 函数根据编码方案将负载(可能是非 JSON 数据)编码为其字符串表示形式。目前,只支持"base64" 编码类型。        |
-| trunc            | trunc(dec, int)                  | 将第一个参数截断为第二个参数指定的小数位数。 如果第二个参数小于零,则将其设置为零。 如果第二个参数大于34,则将其设置为34。从结果中去除尾随零。 |
-| object_construct | object_construct(key1, col, ...) | 返回由参数构建的 oject/map 。参数为一系列的键值对,因此必须为偶数个。键必须为 string 类型,值可以为任意类型。           |
+| 函数               | 示例                               | 说明                                                                                      |
+|------------------|----------------------------------|-----------------------------------------------------------------------------------------|
+| cast             | cast(col,  "bigint")             | 将值从一种数据类型转换为另一种数据类型。 支持的类型包括:bigint,float,string,boolean 和 datetime。                    |
+| chr              | chr(col1)                        | 返回与给定 Int 参数对应的 ASCII 字符                                                                |
+| encode           | encode(col1, "base64")           | 使用 encode 函数根据编码方案将负载(可能是非 JSON 数据)编码为其字符串表示形式。目前,只支持"base64" 编码类型。                     |
+| trunc            | trunc(dec, int)                  | 将第一个参数截断为第二个参数指定的小数位数。 如果第二个参数小于零,则将其设置为零。 如果第二个参数大于34,则将其设置为34。从结果中去除尾随零。              |
+| object_construct | object_construct(key1, col, ...) | 返回由参数构建的 oject/map 。参数为一系列的键值对,因此必须为偶数个。键必须为 string 类型,值可以为任意类型。如果值为空,则该键值对不会出现在最终的对象中。 |
 
 
 ### 转换为 datetime 类型
 ### 转换为 datetime 类型
 
 

+ 6 - 4
internal/binder/function/funcs_misc.go

@@ -517,11 +517,13 @@ func registerMiscFunc() {
 		exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
 		exec: func(ctx api.FunctionContext, args []interface{}) (interface{}, bool) {
 			result := make(map[string]interface{})
 			result := make(map[string]interface{})
 			for i := 0; i < len(args); i += 2 {
 			for i := 0; i < len(args); i += 2 {
-				s, err := cast.ToString(args[i], cast.CONVERT_SAMEKIND)
-				if err != nil {
-					return fmt.Errorf("key %v is not a string", args[i]), false
+				if args[i+1] != nil {
+					s, err := cast.ToString(args[i], cast.CONVERT_SAMEKIND)
+					if err != nil {
+						return fmt.Errorf("key %v is not a string", args[i]), false
+					}
+					result[s] = args[i+1]
 				}
 				}
-				result[s] = args[i+1]
 			}
 			}
 			return result, true
 			return result, true
 		},
 		},

+ 1 - 12
pkg/cast/cast.go

@@ -1,4 +1,4 @@
-// Copyright 2021 EMQ Technologies Co., Ltd.
+// Copyright 2021-2022 EMQ Technologies Co., Ltd.
 //
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
 // you may not use this file except in compliance with the License.
@@ -17,7 +17,6 @@ package cast
 import (
 import (
 	"fmt"
 	"fmt"
 	"github.com/mitchellh/mapstructure"
 	"github.com/mitchellh/mapstructure"
-	"html/template"
 	"reflect"
 	"reflect"
 	"strconv"
 	"strconv"
 	"sync"
 	"sync"
@@ -78,16 +77,6 @@ func ToString(input interface{}, sn Strictness) (string, error) {
 				return strconv.FormatUint(uint64(s), 10), nil
 				return strconv.FormatUint(uint64(s), 10), nil
 			case uint8:
 			case uint8:
 				return strconv.FormatUint(uint64(s), 10), nil
 				return strconv.FormatUint(uint64(s), 10), nil
-			case template.HTML:
-				return string(s), nil
-			case template.URL:
-				return string(s), nil
-			case template.JS:
-				return string(s), nil
-			case template.CSS:
-				return string(s), nil
-			case template.HTMLAttr:
-				return string(s), nil
 			case nil:
 			case nil:
 				return "", nil
 				return "", nil
 			case fmt.Stringer:
 			case fmt.Stringer:

+ 2 - 0
pkg/infra/saferun.go

@@ -18,6 +18,7 @@ import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"github.com/lf-edge/ekuiper/pkg/api"
 	"github.com/lf-edge/ekuiper/pkg/api"
+	"runtime/debug"
 )
 )
 
 
 // SafeRun will catch and return the panic error together with other errors
 // SafeRun will catch and return the panic error together with other errors
@@ -28,6 +29,7 @@ import (
 func SafeRun(fn func() error) (err error) {
 func SafeRun(fn func() error) (err error) {
 	defer func() {
 	defer func() {
 		if r := recover(); r != nil {
 		if r := recover(); r != nil {
+			debug.PrintStack()
 			switch x := r.(type) {
 			switch x := r.(type) {
 			case string:
 			case string:
 				err = errors.New(x)
 				err = errors.New(x)