emqx_rule_sqlparser.erl 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2023 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_rule_sqlparser).
  17. -include("rule_engine.hrl").
  18. -export([parse/1]).
  19. -export([
  20. select_fields/1,
  21. select_is_foreach/1,
  22. select_doeach/1,
  23. select_incase/1,
  24. select_from/1,
  25. select_where/1
  26. ]).
  27. -import(proplists, [
  28. get_value/2,
  29. get_value/3
  30. ]).
  31. -record(select, {fields, from, where, is_foreach, doeach, incase}).
  32. -opaque select() :: #select{}.
  33. -type const() :: {const, number() | binary()}.
  34. -type variable() :: binary() | list(binary()).
  35. -type alias() :: binary() | list(binary()).
  36. -type field() ::
  37. const()
  38. | variable()
  39. | {as, field(), alias()}
  40. | {'fun', atom(), list(field())}.
  41. -export_type([select/0]).
  42. %% Parse one select statement.
  43. -spec parse(string() | binary()) -> {ok, select()} | {error, term()}.
  44. parse(Sql) ->
  45. try
  46. case rulesql:parsetree(Sql) of
  47. {ok, {select, Clauses}} ->
  48. {ok, #select{
  49. is_foreach = false,
  50. fields = get_value(fields, Clauses),
  51. doeach = [],
  52. incase = {},
  53. from = get_value(from, Clauses),
  54. where = get_value(where, Clauses)
  55. }};
  56. {ok, {foreach, Clauses}} ->
  57. {ok, #select{
  58. is_foreach = true,
  59. fields = get_value(fields, Clauses),
  60. doeach = get_value(do, Clauses, []),
  61. incase = get_value(incase, Clauses, {}),
  62. from = get_value(from, Clauses),
  63. where = get_value(where, Clauses)
  64. }};
  65. Error ->
  66. {error, Error}
  67. end
  68. catch
  69. _Error:Reason:StackTrace ->
  70. {error, {Reason, StackTrace}}
  71. end.
  72. -spec select_fields(select()) -> list(field()).
  73. select_fields(#select{fields = Fields}) ->
  74. Fields.
  75. -spec select_is_foreach(select()) -> boolean().
  76. select_is_foreach(#select{is_foreach = IsForeach}) ->
  77. IsForeach.
  78. -spec select_doeach(select()) -> list(field()).
  79. select_doeach(#select{doeach = DoEach}) ->
  80. DoEach.
  81. -spec select_incase(select()) -> list(field()).
  82. select_incase(#select{incase = InCase}) ->
  83. InCase.
  84. -spec select_from(select()) -> list(binary()).
  85. select_from(#select{from = From}) ->
  86. From.
  87. -spec select_where(select()) -> tuple().
  88. select_where(#select{where = Where}) ->
  89. Where.