expr_test.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package ast
  2. import (
  3. "math"
  4. "regexp"
  5. "testing"
  6. "github.com/lf-edge/ekuiper/internal/testx"
  7. )
  8. func init() {
  9. testx.InitEnv()
  10. }
  11. func Test_exprStringPlan(t *testing.T) {
  12. re1, _ := regexp.Compile("^foo$")
  13. test := []struct {
  14. e Expr
  15. res string
  16. }{
  17. {
  18. e: &BetweenExpr{
  19. Lower: &IntegerLiteral{
  20. Val: 0,
  21. },
  22. Higher: &IntegerLiteral{
  23. Val: 10,
  24. },
  25. },
  26. res: "betweenExpr:{ 0, 10 }",
  27. },
  28. {
  29. e: &BinaryExpr{
  30. OP: SUBSET,
  31. LHS: &FieldRef{
  32. StreamName: "src1",
  33. Name: "myarray",
  34. },
  35. RHS: &IndexExpr{Index: &FieldRef{
  36. StreamName: "src1",
  37. Name: "temp",
  38. }},
  39. },
  40. res: "binaryExpr:{ src1.myarray[src1.temp] }",
  41. },
  42. {
  43. e: &BooleanLiteral{Val: true},
  44. res: "true",
  45. },
  46. {
  47. e: &Call{Name: "count", FuncId: 0, Args: []Expr{&Wildcard{
  48. Token: ASTERISK,
  49. }}, FuncType: FuncTypeAgg},
  50. res: "Call:{ name:count, args:[*] }",
  51. },
  52. {
  53. e: &CaseExpr{
  54. WhenClauses: []*WhenClause{
  55. {
  56. Expr: &BinaryExpr{
  57. OP: BETWEEN,
  58. LHS: &Call{
  59. Name: "lag",
  60. FuncId: 0,
  61. FuncType: FuncType(0),
  62. Args: []Expr{
  63. &FieldRef{
  64. StreamName: "src1",
  65. Name: "temp",
  66. },
  67. },
  68. CachedField: "$$a_lag_0",
  69. Cached: true,
  70. WhenExpr: &BinaryExpr{
  71. OP: GT,
  72. LHS: &Call{
  73. Name: "lag",
  74. FuncId: 1,
  75. FuncType: FuncType(0),
  76. Args: []Expr{
  77. &FieldRef{
  78. StreamName: "src1",
  79. Name: "id1",
  80. },
  81. },
  82. CachedField: "$$a_lag_1",
  83. Cached: true,
  84. },
  85. RHS: &IntegerLiteral{
  86. Val: 1,
  87. },
  88. },
  89. },
  90. RHS: &BetweenExpr{
  91. Lower: &IntegerLiteral{
  92. Val: 0,
  93. },
  94. Higher: &IntegerLiteral{
  95. Val: 10,
  96. },
  97. },
  98. },
  99. Result: &IntegerLiteral{
  100. Val: 1,
  101. },
  102. },
  103. {
  104. &BinaryExpr{
  105. OP: BETWEEN,
  106. LHS: &Call{
  107. Name: "lag",
  108. FuncId: 0,
  109. FuncType: FuncType(0),
  110. Args: []Expr{
  111. &FieldRef{
  112. StreamName: "src1",
  113. Name: "temp",
  114. },
  115. },
  116. CachedField: "$$a_lag_0",
  117. Cached: true,
  118. WhenExpr: &BinaryExpr{
  119. OP: GT,
  120. LHS: &Call{
  121. Name: "lag",
  122. FuncId: 1,
  123. FuncType: FuncType(0),
  124. Args: []Expr{
  125. &FieldRef{
  126. StreamName: "src1",
  127. Name: "id1",
  128. },
  129. },
  130. CachedField: "$$a_lag_1",
  131. Cached: true,
  132. },
  133. RHS: &IntegerLiteral{
  134. Val: 1,
  135. },
  136. },
  137. },
  138. RHS: &BetweenExpr{
  139. Lower: &IntegerLiteral{
  140. Val: 0,
  141. },
  142. Higher: &IntegerLiteral{
  143. Val: 10,
  144. },
  145. },
  146. },
  147. &IntegerLiteral{
  148. Val: 2,
  149. },
  150. },
  151. },
  152. ElseClause: &IntegerLiteral{
  153. Val: 0,
  154. },
  155. Value: &IntegerLiteral{
  156. Val: 12,
  157. },
  158. },
  159. res: "caseExprValue:{ value:{ 12 }, whenClauses:[{ whenClause:{ binaryExpr:{ Call:{ name:lag, args:[src1.temp], when:{ binaryExpr:{ Call:{ name:lag, args:[src1.id1] } > 1 } } } BETWEEN betweenExpr:{ 0, 10 } } } }, { whenClause:{ binaryExpr:{ Call:{ name:lag, args:[src1.temp], when:{ binaryExpr:{ Call:{ name:lag, args:[src1.id1] } > 1 } } } BETWEEN betweenExpr:{ 0, 10 } } } }] }",
  160. },
  161. {
  162. e: &JsonFieldRef{Name: "Device"},
  163. res: "jsonFieldName:Device",
  164. },
  165. {
  166. e: &NumberLiteral{Val: 1.23},
  167. res: "1.230000",
  168. },
  169. {
  170. e: &StringLiteral{Val: "v1"},
  171. res: "v1",
  172. },
  173. {
  174. e: &TimeLiteral{Val: 2},
  175. res: "WS",
  176. },
  177. {
  178. e: &MetaRef{
  179. Name: "device",
  180. StreamName: DefaultStream,
  181. },
  182. res: "metaRef:{ streamName:$$default, fieldName:device }",
  183. },
  184. {
  185. e: &PartitionExpr{Exprs: []Expr{&FieldRef{Name: "temp", StreamName: "src1"}, &FieldRef{Name: "current", StreamName: "src2"}}},
  186. res: "PartitionExpr:[ src1.temp, src2.current ]",
  187. },
  188. {
  189. e: &SortField{Uname: "name", Name: "name", Ascending: true, FieldExpr: &FieldRef{Name: "name", StreamName: DefaultStream}},
  190. res: "sortField:{ name:name, ascending:true, fieldExpr:{ $$default.name } }",
  191. },
  192. {
  193. e: &BracketExpr{Expr: &ColonExpr{Start: &IntegerLiteral{Val: 0}, End: &IntegerLiteral{Val: math.MinInt32}}},
  194. res: "bracketExpr:{ ColonExpr:{ start:{ 0 }, end:{ -2147483648 } } }",
  195. },
  196. {
  197. e: &ArrowExpr{Expr: &ColonExpr{Start: &IntegerLiteral{Val: 0}, End: &IntegerLiteral{Val: math.MinInt32}}},
  198. res: "arrowExpr:{ ColonExpr:{ start:{ 0 }, end:{ -2147483648 } } }",
  199. },
  200. {
  201. e: &ValueSetExpr{
  202. LiteralExprs: []Expr{&StringLiteral{"A"}, &StringLiteral{"B"}},
  203. ArrayExpr: &StringLiteral{"A, B"},
  204. },
  205. res: "valueSetExpr:{ literalExprs:[A, B], arrayExpr:{ A, B } }",
  206. },
  207. {
  208. e: &ColFuncField{
  209. Name: "ABC",
  210. Expr: &StringLiteral{Val: ""},
  211. },
  212. res: "colFuncField:{ name: ABC, expr:{ } }",
  213. },
  214. {
  215. e: &LikePattern{Expr: &StringLiteral{Val: "foo"}, Pattern: re1},
  216. res: "likePattern:^foo$",
  217. },
  218. {
  219. e: &LimitExpr{
  220. LimitCount: &IntegerLiteral{Val: 10},
  221. },
  222. res: "limitExpr:{ 10 }",
  223. },
  224. }
  225. for i := 0; i < len(test); i++ {
  226. res := test[i].res
  227. str := test[i].e.String()
  228. if str != res {
  229. t.Errorf("case %d: expect validate %v but got %v", i, res, str)
  230. }
  231. }
  232. }