%%-------------------------------------------------------------------- %% Copyright (c) 2020-2023 EMQ Technologies Co., Ltd. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %%-------------------------------------------------------------------- -module(emqx_rule_sqlparser). -include("rule_engine.hrl"). -export([parse/1]). -export([ select_fields/1, select_is_foreach/1, select_doeach/1, select_incase/1, select_from/1, select_where/1 ]). -import(proplists, [ get_value/2, get_value/3 ]). -record(select, {fields, from, where, is_foreach, doeach, incase}). -opaque select() :: #select{}. -type const() :: {const, number() | binary()}. -type variable() :: binary() | list(binary()). -type alias() :: binary() | list(binary()). -type field() :: const() | variable() | {as, field(), alias()} | {'fun', atom(), list(field())}. -export_type([select/0]). %% Parse one select statement. -spec parse(string() | binary()) -> {ok, select()} | {error, term()}. parse(Sql) -> try case rulesql:parsetree(Sql) of {ok, {select, Clauses}} -> {ok, #select{ is_foreach = false, fields = get_value(fields, Clauses), doeach = [], incase = {}, from = get_value(from, Clauses), where = get_value(where, Clauses) }}; {ok, {foreach, Clauses}} -> {ok, #select{ is_foreach = true, fields = get_value(fields, Clauses), doeach = get_value(do, Clauses, []), incase = get_value(incase, Clauses, {}), from = get_value(from, Clauses), where = get_value(where, Clauses) }}; Error -> {error, Error} end catch _Error:Reason:StackTrace -> {error, {Reason, StackTrace}} end. -spec select_fields(select()) -> list(field()). select_fields(#select{fields = Fields}) -> Fields. -spec select_is_foreach(select()) -> boolean(). select_is_foreach(#select{is_foreach = IsForeach}) -> IsForeach. -spec select_doeach(select()) -> list(field()). select_doeach(#select{doeach = DoEach}) -> DoEach. -spec select_incase(select()) -> list(field()). select_incase(#select{incase = InCase}) -> InCase. -spec select_from(select()) -> list(binary()). select_from(#select{from = From}) -> From. -spec select_where(select()) -> tuple(). select_where(#select{where = Where}) -> Where.