function.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright 2021 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package function
  15. import (
  16. "fmt"
  17. "github.com/lf-edge/ekuiper/pkg/api"
  18. "github.com/lf-edge/ekuiper/pkg/ast"
  19. "strings"
  20. )
  21. type funcType int
  22. const (
  23. NotFoundFunc funcType = iota - 1
  24. AggFunc
  25. MathFunc
  26. StrFunc
  27. ConvFunc
  28. HashFunc
  29. JsonFunc
  30. OtherFunc
  31. )
  32. var maps = []map[string]string{
  33. aggFuncMap, mathFuncMap, strFuncMap, convFuncMap, hashFuncMap, jsonFuncMap, otherFuncMap,
  34. }
  35. var aggFuncMap = map[string]string{"avg": "",
  36. "count": "",
  37. "max": "", "min": "",
  38. "sum": "",
  39. "collect": "",
  40. "deduplicate": "",
  41. }
  42. var funcWithAsteriskSupportMap = map[string]string{
  43. "collect": "",
  44. "count": "",
  45. }
  46. var mathFuncMap = map[string]string{"abs": "", "acos": "", "asin": "", "atan": "", "atan2": "",
  47. "bitand": "", "bitor": "", "bitxor": "", "bitnot": "",
  48. "ceil": "", "cos": "", "cosh": "",
  49. "exp": "",
  50. "ln": "", "log": "",
  51. "mod": "",
  52. "power": "",
  53. "rand": "", "round": "",
  54. "sign": "", "sin": "", "sinh": "", "sqrt": "",
  55. "tan": "", "tanh": "",
  56. }
  57. var strFuncMap = map[string]string{"concat": "",
  58. "endswith": "",
  59. "format_time": "",
  60. "indexof": "",
  61. "length": "", "lower": "", "lpad": "", "ltrim": "",
  62. "numbytes": "",
  63. "regexp_matches": "", "regexp_replace": "", "regexp_substr": "", "rpad": "", "rtrim": "",
  64. "substring": "", "startswith": "", "split_value": "",
  65. "trim": "",
  66. "upper": "",
  67. }
  68. var convFuncMap = map[string]string{"concat": "", "cast": "", "chr": "",
  69. "encode": "",
  70. "trunc": "",
  71. }
  72. var hashFuncMap = map[string]string{"md5": "",
  73. "sha1": "", "sha256": "", "sha384": "", "sha512": "",
  74. }
  75. var jsonFuncMap = map[string]string{
  76. "json_path_query": "", "json_path_query_first": "", "json_path_exists": "",
  77. }
  78. var otherFuncMap = map[string]string{"isnull": "",
  79. "newuuid": "", "tstamp": "", "mqtt": "", "meta": "", "cardinality": "",
  80. "window_start": "",
  81. "window_end": "",
  82. }
  83. func getFuncType(name string) funcType {
  84. for i, m := range maps {
  85. if _, ok := m[strings.ToLower(name)]; ok {
  86. return funcType(i)
  87. }
  88. }
  89. return NotFoundFunc
  90. }
  91. type funcExecutor struct{}
  92. func (f *funcExecutor) ValidateWithName(args []ast.Expr, name string) error {
  93. var eargs []ast.Expr
  94. for _, arg := range args {
  95. if t, ok := arg.(ast.Expr); ok {
  96. eargs = append(eargs, t)
  97. } else {
  98. // should never happen
  99. return fmt.Errorf("receive invalid arg %v", arg)
  100. }
  101. }
  102. return validateFuncs(name, eargs)
  103. }
  104. func (f *funcExecutor) Validate(_ []interface{}) error {
  105. return fmt.Errorf("unknow name")
  106. }
  107. func (f *funcExecutor) Exec(_ []interface{}, _ api.FunctionContext) (interface{}, bool) {
  108. return fmt.Errorf("unknow name"), false
  109. }
  110. func (f *funcExecutor) ExecWithName(args []interface{}, _ api.FunctionContext, name string) (interface{}, bool) {
  111. lowerName := strings.ToLower(name)
  112. switch getFuncType(lowerName) {
  113. case AggFunc:
  114. return aggCall(lowerName, args)
  115. case MathFunc:
  116. return mathCall(lowerName, args)
  117. case ConvFunc:
  118. return convCall(lowerName, args)
  119. case StrFunc:
  120. return strCall(lowerName, args)
  121. case HashFunc:
  122. return hashCall(lowerName, args)
  123. case JsonFunc:
  124. return jsonCall(lowerName, args)
  125. case OtherFunc:
  126. return otherCall(lowerName, args)
  127. }
  128. return fmt.Errorf("unknow name"), false
  129. }
  130. func (f *funcExecutor) IsAggregate() bool {
  131. return false
  132. }
  133. func (f *funcExecutor) IsAggregateWithName(name string) bool {
  134. lowerName := strings.ToLower(name)
  135. return getFuncType(lowerName) == AggFunc
  136. }
  137. var staticFuncExecutor = &funcExecutor{}
  138. type Manager struct{}
  139. func (m *Manager) Function(name string) (api.Function, error) {
  140. ft := getFuncType(name)
  141. if ft != NotFoundFunc {
  142. return staticFuncExecutor, nil
  143. }
  144. return nil, nil
  145. }
  146. func (m *Manager) HasFunctionSet(name string) bool {
  147. return name == "internal"
  148. }
  149. var m = &Manager{}
  150. func GetManager() *Manager {
  151. return m
  152. }