function.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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[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{}, ctx api.FunctionContext, name string) (interface{}, bool) {
  111. switch getFuncType(name) {
  112. case AggFunc:
  113. return aggCall(name, args)
  114. case MathFunc:
  115. return mathCall(name, args)
  116. case ConvFunc:
  117. return convCall(name, args)
  118. case StrFunc:
  119. return strCall(name, args)
  120. case HashFunc:
  121. return hashCall(name, args)
  122. case JsonFunc:
  123. return jsonCall(ctx, name, args)
  124. case OtherFunc:
  125. return otherCall(name, args)
  126. }
  127. return fmt.Errorf("unknow name"), false
  128. }
  129. func (f *funcExecutor) IsAggregate() bool {
  130. return false
  131. }
  132. func (f *funcExecutor) IsAggregateWithName(name string) bool {
  133. return getFuncType(name) == AggFunc
  134. }
  135. var staticFuncExecutor = &funcExecutor{}
  136. type Manager struct{}
  137. func (m *Manager) Function(name string) (api.Function, error) {
  138. ft := getFuncType(name)
  139. if ft != NotFoundFunc {
  140. return staticFuncExecutor, nil
  141. }
  142. return nil, nil
  143. }
  144. func (m *Manager) HasFunctionSet(name string) bool {
  145. return name == "internal"
  146. }
  147. func (m *Manager) ConvName(n string) (string, bool) {
  148. name := strings.ToLower(n)
  149. ft := getFuncType(name)
  150. if ft != NotFoundFunc {
  151. return name, true
  152. }
  153. return name, false
  154. }
  155. var m = &Manager{}
  156. func GetManager() *Manager {
  157. return m
  158. }