From b7109f1832c5996362cf6c9c63fbc27d8e5bb7e3 Mon Sep 17 00:00:00 2001 From: Benjamin Schultzer Date: Thu, 31 Jul 2025 14:11:19 -0400 Subject: [PATCH] Add compile time warnings --- .iex.exs | 6 + CHANGELOG.md | 8 +- README.md | 18 +- bench.exs | 2 +- lib/adapters/ansi.ex | 137 ++- lib/adapters/mysql.ex | 3 + lib/adapters/postgres.ex | 21 + lib/adapters/tds.ex | 7 + lib/bnf.ex | 2 +- lib/formatter.ex | 2 +- lib/helpers.ex | 1512 +++++++++++++++--------------- lib/lexer.ex | 11 +- lib/mix/tasks/sql.gen.helpers.ex | 3 +- lib/mix/tasks/sql.gen.test.ex | 117 +-- lib/mix/tasks/sql.get.ex | 55 ++ lib/parser.ex | 174 ++-- lib/sql.ex | 140 ++- lib/token.ex | 23 +- mix.exs | 2 + mix.lock | 2 + sql.lock | 1 + test/formatter_test.exs | 2 +- test/parser_test.exs | 44 + test/sql_test.exs | 8 +- test/test_helper.exs | 5 + 25 files changed, 1366 insertions(+), 939 deletions(-) create mode 100644 lib/mix/tasks/sql.get.ex create mode 100644 sql.lock create mode 100644 test/parser_test.exs diff --git a/.iex.exs b/.iex.exs index 5321080..18adffb 100644 --- a/.iex.exs +++ b/.iex.exs @@ -4,6 +4,12 @@ defmodule SQL.Repo do use Ecto.Repo, otp_app: :sql, adapter: Ecto.Adapters.Postgres end +Application.put_env(:sql, :driver, Postgrex) +Application.put_env(:sql, :username, "postgres") +Application.put_env(:sql, :password, "postgres") +Application.put_env(:sql, :hostname, "localhost") +Application.put_env(:sql, :database, "sql_test#{System.get_env("MIX_TEST_PARTITION")}") +Application.put_env(:sql, :adapter, SQL.Adapters.Postgres) Application.put_env(:sql, :ecto_repos, [SQL.Repo]) Application.put_env(:sql, SQL.Repo, username: "postgres", password: "postgres", hostname: "localhost", database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}", pool: Ecto.Adapters.SQL.Sandbox, pool_size: 10) Mix.Tasks.Ecto.Create.run(["-r", "SQL.Repo"]) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62db244..06b7786 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,19 @@ ## v0.3.0 (2025-08-01) ### Enhancement - - Improve SQL generation with 57-344x compared to Ecto [#12](https://github.com/elixir-dbvisor/sql/pull/12). + - Improve SQL generation with over 100x compared to Ecto [#12](https://github.com/elixir-dbvisor/sql/pull/12), [#19](https://github.com/elixir-dbvisor/sql/pull/19). - Fix bug for complex CTE [#15](https://github.com/elixir-dbvisor/sql/pull/15). Thanks to @kafaichoi - Support for PostgresSQL GiST operators [#18](https://github.com/elixir-dbvisor/sql/pull/18). Thanks to @ibarchenkov - `float` and `integer` nodes have now become `numeric` with metadata to distinguish `sign`, `whole` and `fractional` [#19](https://github.com/elixir-dbvisor/sql/pull/19). - `keyword` nodes are now `ident` with metadata distinguish if it's a `keyword` [#19](https://github.com/elixir-dbvisor/sql/pull/19). - `SQL.Lexer.lex/4` now returns `{:ok, context, tokens}` [#19](https://github.com/elixir-dbvisor/sql/pull/19). - `SQL.Parser.parse/1` has become `SQL.Parser.parse/2` and takes `tokens` and `context` from `SQL.Lexer.lex/4` and returns `{:ok, context, tokens}` or raises an error [#19](https://github.com/elixir-dbvisor/sql/pull/19). + - Support for compile time warnings on missing relations in a query. [#22](https://github.com/elixir-dbvisor/sql/pull/22) + - `mix sql.get` creates a lock file which are used to generate warnings at compile time. [#22](https://github.com/elixir-dbvisor/sql/pull/22) + - Support SQL formatting. [#22](https://github.com/elixir-dbvisor/sql/pull/22) + +### Deprecation + - token_to_string/2 is deprecated in favor of to_iodata/3 [#22](https://github.com/elixir-dbvisor/sql/pull/22). ## v0.2.0 (2025-05-04) diff --git a/README.md b/README.md index 3fdf6a0..3e4baba 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,30 @@ iex(1)> email = "john@example.com" "john@example.com" iex(2)> ~SQL[from users] |> ~SQL[where email = {{email}}] |> ~SQL"select id, email" ~SQL""" -where email = {{email}} from users select id, email +select + id, + email +from + users +where + email = {{email}} """ iex(3)> sql = ~SQL[from users where email = {{email}} select id, email] ~SQL""" -from users where email = {{email}} select id, email +select + id, + email +from + users +where + email = {{email}} """ iex(4)> to_sql(sql) {"select id, email from users where email = ?", ["john@example.com"]} iex(5)> to_string(sql) "select id, email from users where email = ?" iex(6)> inspect(sql) -"~SQL\"\"\"\nfrom users where email = {{email}} select id, email\n\"\"\"" +"~SQL\"\"\"\nselect\n id, \n email\nfrom\n users\nwhere\n email = {{email}}\n\"\"\"" ``` ### Leverage the Enumerable protocol in your repository diff --git a/bench.exs b/bench.exs index b5848f9..fe9c188 100644 --- a/bench.exs +++ b/bench.exs @@ -11,7 +11,7 @@ sql = ~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, ( query = "temp" |> recursive_ctes(true) |> with_cte("temp", as: ^union_all(select("temp", [t], %{n: 0, fact: 1}), ^where(select("temp", [t], [t.n+1, t.n+1*t.fact]), [t], t.n < 9))) |> select([t], [t.n]) result = Tuple.to_list(SQL.Lexer.lex("with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)")) tokens = Enum.at(result, -1) -context = Enum.at(result, 1) +context = Map.put(Enum.at(result, 1), :sql_lock, nil) Benchee.run( %{ "comptime to_string" => fn _ -> to_string(sql) end, diff --git a/lib/adapters/ansi.ex b/lib/adapters/ansi.ex index 3956fdd..5b92faa 100644 --- a/lib/adapters/ansi.ex +++ b/lib/adapters/ansi.ex @@ -75,7 +75,7 @@ defmodule SQL.Adapters.ANSI do "#{mod.token_to_string(value)};" end def token_to_string({:comma, _, value}, mod) do - ", #{mod.token_to_string(value)}" + "#{mod.token_to_string(value)}," end def token_to_string({:dot, _, [left, right]}, mod) do "#{mod.token_to_string(left)}.#{mod.token_to_string(right)}" @@ -108,9 +108,140 @@ defmodule SQL.Adapters.ANSI do values |> Enum.reduce([], fn [], acc -> acc - token, [] -> [mod.token_to_string(token)] - {:comma, _, _} = token, acc -> [acc,mod.token_to_string(token)] + {:comma, _, _} = token, acc -> [acc, mod.token_to_string(token), " "] + token, [] -> mod.token_to_string(token) + token, [_, _, " "] = acc -> [acc, mod.token_to_string(token)] + token, [_, " "] = acc -> [acc, mod.token_to_string(token)] token, acc -> [acc, " ", mod.token_to_string(token)] end) end + + @doc false + def to_iodata({tag, _, values}, context, indent) when tag in ~w[inner outer left right full natural cross]a do + [context.module.to_iodata(tag, context, indent),context.module.to_iodata(values, context, indent, [?\s])] + end + def to_iodata({tag, _, values}, context, indent) when tag in ~w[join]a do + v = Enum.reduce(values, [], fn token, acc -> [acc, ?\s, context.module.to_iodata(token, context, indent)] end) + + [indention(indent), context.module.to_iodata(tag, context, indent) | [v, ?\n]] + end + def to_iodata({tag, _, values}, context, indent) when tag in ~w[select from join where group having window order limit offset fetch]a do + v = Enum.reduce(values, [?\n], fn token, acc -> [acc, indention(indent+1), context.module.to_iodata(token, context, indent+1), ?\n] end) + + [indention(indent), context.module.to_iodata(tag, context, indent) | v] + end + def to_iodata({:as, [], [left, right]}, context, indent) do + [context.module.to_iodata(left, context, indent),?\s|context.module.to_iodata(right, context, indent)] + end + def to_iodata({tag, _, [left]}, context, indent) when tag in ~w[asc desc isnull notnull]a do + [context.module.to_iodata(left, context, indent),?\s|context.module.to_iodata(tag, context, indent)] + end + def to_iodata({:fun, _, [left, right]}, context, indent) do + [context.module.to_iodata(left, context, indent)|context.module.to_iodata(right, context, indent)] + end + def to_iodata({tag, [{:type, :operator}|_], [left, {:paren, _, _} = right]}, context, indent) do + [context.module.to_iodata(left, context, indent),?\s,context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(right, context, indent)] + end + def to_iodata({tag, [{:type, :operator}|_], [left, right]}, context, indent) do + [context.module.to_iodata(left, context, indent),?\s,context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(right, context, indent)] + end + def to_iodata({:ident, [{:type, :non_reserved},{:tag, tag}|_], [{:paren, _, _} = value]}, context, indent) do + [context.module.to_iodata(tag, context, indent)|context.module.to_iodata(value, context, indent)] + end + def to_iodata({:ident, [{:type, :non_reserved}, {:tag, tag}|_], [{:numeric, _, _} = value]}, context, indent) do + [context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(value, context, indent)] + end + def to_iodata({:ident, [{:type, :non_reserved}, {:tag, tag}|_], _}, context, indent) do + context.module.to_iodata(tag, context, indent) + end + def to_iodata({tag, [{:type, :reserved}|_], [{:paren, _, _} = value]}, context, indent) when tag not in ~w[on in select]a do + [context.module.to_iodata(tag, context, indent)|context.module.to_iodata(value, context, indent)] + end + def to_iodata({tag, [{:type, :reserved}|_], []}, context, indent) do + [?\s, context.module.to_iodata(tag, context, indent)] + end + def to_iodata({tag, _, [left, {:all = t, _, right}]}, context, indent) when tag in ~w[union except intersect]a do + [context.module.to_iodata(left, context, indent), indention(indent), context.module.to_iodata(tag, context, indent),?\s,context.module.to_iodata(t, context, indent),?\n|context.module.to_iodata(right, context, indent)] + end + def to_iodata({:between = tag, _, [{:not = t, _, right}, left]}, context, indent) do + [context.module.to_iodata(right, context, indent),?\s,context.module.to_iodata(t, context, indent),?\s,context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(left, context, indent)] + end + def to_iodata({:binding, _, [idx]}, %{format: true, binding: binding}, _indent) do + [?{,?{,Macro.to_string(Enum.at(binding, idx-1))|[?},?}]] + end + def to_iodata({:binding, _, _}, _context, _indent) do + [??] + end + def to_iodata({:comment, _, value}, _context, _indent) do + [?-,?-|value] + end + def to_iodata({:comments, _, value}, _context, _indent) do + [?\\,?*,value|[?*, ?\\]] + end + def to_iodata({:double_quote, _, value}=node, context, _indent) do + case node in context.errors do + true -> [[?",:red,value|[:reset, ?"]]] + false -> value + end + end + def to_iodata({:quote, _, value}, _context, _indent) do + [?',value|[?']] + end + def to_iodata({:paren, _, [{_,[{:type, :reserved}|_],_}|_] = value}, context, indent) do + [?(,?\n, context.module.to_iodata(value, context, indent+1)|?)] + end + def to_iodata({:paren, _, value}, context, indent) do + [?(,context.module.to_iodata(value, context, indent)|[?)]] + end + def to_iodata({:bracket, _, value}, context, indent) do + [?[,context.module.to_iodata(value, context, indent)|[?]]] + end + def to_iodata({:colon, _, value}, context, indent) do + [context.module.to_iodata(value, context, indent)|[?;,?\n]] + end + def to_iodata({:comma, _, value}, context, indent) do + [context.module.to_iodata(value, context, indent), ?,, ?\s] + end + def to_iodata({:dot, _, [left, right]}, context, indent) do + [context.module.to_iodata(left, context, indent),?\.|context.module.to_iodata(right, context, indent)] + end + def to_iodata({tag, _, value} = node, context, _indent) when tag in ~w[ident numeric]a do + case node in context.errors do + true -> [:red, value, :reset] + false -> value + end + end + def to_iodata(value, _context, _indent) when is_atom(value) do + ~c"#{value}" + end + def to_iodata(value, _context, _indent) when is_binary(value) do + [?',value|[?']] + end + def to_iodata(value, _context, _indent) when is_integer(value) do + [value] + end + def to_iodata(value, _context, _indent) when is_struct(value) do + to_string(value) + end + def to_iodata({tag, _, [left, right]}, context, indent) when tag in ~w[like ilike union except intersect between and or is not in cursor for to]a do + [context.module.to_iodata(left, context, indent),?\s,context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(right, context, indent)] + end + def to_iodata({tag, [{:type, :reserved}|_], values}, context, indent) do + [context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(values, context, indent)] + end + def to_iodata({tag, [{:type, :non_reserved}|_], values}, context, indent) when tag != :ident do + [context.module.to_iodata(tag, context, indent),?\s|context.module.to_iodata(values, context, indent)] + end + def to_iodata({tag, _, []}, context, indent) do + [indention(indent), context.module.to_iodata(tag, context, indent)] + end + def to_iodata([[{_,_,_}|_]|_]=tokens, context, indent) do + to_iodata(tokens, context, indent, []) + end + def to_iodata([{_,_,_}|_]=tokens, context, indent) do + to_iodata(tokens, context, indent, []) + end + def to_iodata([]=tokens, _context, _indent) do + tokens + end end diff --git a/lib/adapters/mysql.ex b/lib/adapters/mysql.ex index 4147d89..74ecd25 100644 --- a/lib/adapters/mysql.ex +++ b/lib/adapters/mysql.ex @@ -12,4 +12,7 @@ defmodule SQL.Adapters.MySQL do @doc false def token_to_string(value, mod \\ __MODULE__) def token_to_string(token, mod), do: SQL.Adapters.ANSI.token_to_string(token, mod) + + @doc false + def to_iodata(token, context, indent), do: SQL.Adapters.ANSI.to_iodata(token, context, indent) end diff --git a/lib/adapters/postgres.ex b/lib/adapters/postgres.ex index 98b4ad1..c232e56 100644 --- a/lib/adapters/postgres.ex +++ b/lib/adapters/postgres.ex @@ -18,4 +18,25 @@ defmodule SQL.Adapters.Postgres do "#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}" end def token_to_string(token, mod), do: SQL.Adapters.ANSI.token_to_string(token, mod) + + @doc false + def to_iodata({:not, _, [left, {:in, _, [{:binding, _, [idx]}]}]}, %{format: true, binding: binding} = context, indent) do + [context.module.to_iodata(left, context, indent), ?\s, ?{,?{,Macro.to_string(Enum.at(binding, idx-1)),?},?}] + end + def to_iodata({:not, _, [left, {:in, _, [{:binding, _, _} = right]}]}, context, indent) do + [context.module.to_iodata(left, context, indent), ?!, ?=, ?A,?N,?Y,?(, context.module.to_iodata(right, context, indent), ?)] + end + def to_iodata({:in, _, [left, {:binding, _, [idx]}]}, %{format: true, binding: binding} = context, indent) do + [context.module.to_iodata(left, context, indent), ?\s, ?{,?{,Macro.to_string(Enum.at(binding, idx-1)),?},?}] + end + def to_iodata({:in, _, [left, {:binding, _, _} = right]}, context, indent) do + [context.module.to_iodata(left, context, indent), ?=, ?A,?N,?Y,?(, context.module.to_iodata(right, context, indent), ?)] + end + def to_iodata({:binding, _, [idx]}, %{format: true, binding: binding}, _indent) do + [?{,?{,Macro.to_string(Enum.at(binding, idx-1))|[?},?}]] + end + def to_iodata({:binding, _, [idx]}, _context, _indent) do + ~c"$#{idx}" + end + def to_iodata(token, context, indent), do: SQL.Adapters.ANSI.to_iodata(token, context, indent) end diff --git a/lib/adapters/tds.ex b/lib/adapters/tds.ex index a4b564e..98ab7eb 100644 --- a/lib/adapters/tds.ex +++ b/lib/adapters/tds.ex @@ -13,4 +13,11 @@ defmodule SQL.Adapters.TDS do def token_to_string(value, mod \\ __MODULE__) def token_to_string({:binding, _, [idx]}, _mod) when is_integer(idx), do: "@#{idx}" def token_to_string(token, mod), do: SQL.Adapters.ANSI.token_to_string(token, mod) + + @doc false + def to_iodata({:binding, _, [idx]}, %{format: true, binding: binding}, _indent) do + [?{,?{,Macro.to_string(Enum.at(binding, idx-1))|[?},?}]] + end + def to_iodata({:binding, _, [idx]}, _context, _indent) when is_integer(idx), do: ~c"@#{idx}" + def to_iodata(token, context, indent), do: SQL.Adapters.ANSI.to_iodata(token, context, indent) end diff --git a/lib/bnf.ex b/lib/bnf.ex index 2dd5c13..976ee78 100644 --- a/lib/bnf.ex +++ b/lib/bnf.ex @@ -43,7 +43,7 @@ defmodule SQL.BNF do cond do String.ends_with?(r, "word>") == true -> e = if is_map_key(opts, r), do: e ++ opts[r], else: e - {[{r, (for v <- e, v != "|", do: {atom(v), match(v), guard(v)})} | keywords], operators, letters, digits, terminals} + {[{r, (for v <- e, v not in ["|", "AS"], do: {atom(v), match(v), guard(v)})} | keywords], operators, letters, digits, terminals} String.ends_with?(r, "letter>") == true -> {keywords, operators, [{r, Enum.reject(e, &(&1 == "|"))}|letters], digits, terminals} String.ends_with?(r, "digit>") == true -> {keywords, operators, letters, [{r, Enum.reject(e, &(&1 == "|"))}|digits], terminals} String.ends_with?(r, "operator>") == true -> {keywords, [rule | operators], letters, digits, terminals} diff --git a/lib/formatter.ex b/lib/formatter.ex index 2820d41..756e5b1 100644 --- a/lib/formatter.ex +++ b/lib/formatter.ex @@ -9,5 +9,5 @@ defmodule SQL.MixFormatter do def features(opts), do: [sigils: [:SQL], extensions: get_in(opts, [:sql, :extensions])] @impl Mix.Tasks.Format - def format(source, _opts), do: "#{SQL.parse(source)}" + def format(source, _opts), do: SQL.parse(source) end diff --git a/lib/helpers.ex b/lib/helpers.ex index 4eef75f..0471cfc 100644 --- a/lib/helpers.ex +++ b/lib/helpers.ex @@ -17,1512 +17,1512 @@ defmodule SQL.Helpers do defguard is_sign(b) when b in ~c"-+" defguard is_dot(b) when b == ?. defguard is_delimiter(b) when b in ~c";," - + defguard is_a(b) when b in ~c"aA" - + defguard is_b(b) when b in ~c"bB" - + defguard is_c(b) when b in ~c"cC" - + defguard is_d(b) when b in ~c"dD" - + defguard is_e(b) when b in ~c"eE" - + defguard is_f(b) when b in ~c"fF" - + defguard is_g(b) when b in ~c"gG" - + defguard is_h(b) when b in ~c"hH" - + defguard is_i(b) when b in ~c"iI" - + defguard is_j(b) when b in ~c"jJ" - + defguard is_k(b) when b in ~c"kK" - + defguard is_l(b) when b in ~c"lL" - + defguard is_m(b) when b in ~c"mM" - + defguard is_n(b) when b in ~c"nN" - + defguard is_o(b) when b in ~c"oO" - + defguard is_p(b) when b in ~c"pP" - + defguard is_q(b) when b in ~c"qQ" - + defguard is_r(b) when b in ~c"rR" - + defguard is_s(b) when b in ~c"sS" - + defguard is_t(b) when b in ~c"tT" - + defguard is_u(b) when b in ~c"uU" - + defguard is_v(b) when b in ~c"vV" - + defguard is_w(b) when b in ~c"wW" - + defguard is_x(b) when b in ~c"xX" - + defguard is_y(b) when b in ~c"yY" - + defguard is_z(b) when b in ~c"zZ" - - + + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_b(b2) and is_s(b3), do: {:reserved, :abs} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_a(b1) and is_b(b2) and is_s(b3) and is_e(b4) and is_n(b5) and is_t(b6), do: {:reserved, :absent} - + def tag([[[[[], b1], b2], b3], b4]) when is_a(b1) and is_c(b2) and is_o(b3) and is_s(b4), do: {:reserved, :acos} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_l(b2) and is_l(b3), do: {:reserved, :all} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_a(b1) and is_l(b2) and is_l(b3) and is_o(b4) and is_c(b5) and is_a(b6) and is_t(b7) and is_e(b8), do: {:reserved, :allocate} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_a(b1) and is_l(b2) and is_t(b3) and is_e(b4) and is_r(b5), do: {:reserved, :alter} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_n(b2) and is_d(b3), do: {:reserved, :and} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_n(b2) and is_y(b3), do: {:reserved, :any} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_a(b1) and is_n(b2) and is_y(b3) and b4 in ~c"_" and is_v(b5) and is_a(b6) and is_l(b7) and is_u(b8) and is_e(b9), do: {:reserved, :any_value} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_r(b2) and is_e(b3), do: {:reserved, :are} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_a(b1) and is_r(b2) and is_r(b3) and is_a(b4) and is_y(b5), do: {:reserved, :array} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_a(b1) and is_r(b2) and is_r(b3) and is_a(b4) and is_y(b5) and b6 in ~c"_" and is_a(b7) and is_g(b8) and is_g(b9), do: {:reserved, :array_agg} - + def tag([[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21]) when is_a(b1) and is_r(b2) and is_r(b3) and is_a(b4) and is_y(b5) and b6 in ~c"_" and is_m(b7) and is_a(b8) and is_x(b9) and b10 in ~c"_" and is_c(b11) and is_a(b12) and is_r(b13) and is_d(b14) and is_i(b15) and is_n(b16) and is_a(b17) and is_l(b18) and is_i(b19) and is_t(b20) and is_y(b21), do: {:reserved, :array_max_cardinality} - - def tag([[[], b1], b2]) when is_a(b1) and is_s(b2), do: {:reserved, :as} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_a(b1) and is_s(b2) and is_e(b3) and is_n(b4) and is_s(b5) and is_i(b6) and is_t(b7) and is_i(b8) and is_v(b9) and is_e(b10), do: {:reserved, :asensitive} - + def tag([[[[[], b1], b2], b3], b4]) when is_a(b1) and is_s(b2) and is_i(b3) and is_n(b4), do: {:reserved, :asin} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_a(b1) and is_s(b2) and is_y(b3) and is_m(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_r(b8) and is_i(b9) and is_c(b10), do: {:reserved, :asymmetric} - + def tag([[[], b1], b2]) when is_a(b1) and is_t(b2), do: {:reserved, :at} - + def tag([[[[[], b1], b2], b3], b4]) when is_a(b1) and is_t(b2) and is_a(b3) and is_n(b4), do: {:reserved, :atan} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_a(b1) and is_t(b2) and is_o(b3) and is_m(b4) and is_i(b5) and is_c(b6), do: {:reserved, :atomic} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_a(b1) and is_u(b2) and is_t(b3) and is_h(b4) and is_o(b5) and is_r(b6) and is_i(b7) and is_z(b8) and is_a(b9) and is_t(b10) and is_i(b11) and is_o(b12) and is_n(b13), do: {:reserved, :authorization} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_v(b2) and is_g(b3), do: {:reserved, :avg} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_b(b1) and is_e(b2) and is_g(b3) and is_i(b4) and is_n(b5), do: {:reserved, :begin} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_b(b1) and is_e(b2) and is_g(b3) and is_i(b4) and is_n(b5) and b6 in ~c"_" and is_f(b7) and is_r(b8) and is_a(b9) and is_m(b10) and is_e(b11), do: {:reserved, :begin_frame} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_b(b1) and is_e(b2) and is_g(b3) and is_i(b4) and is_n(b5) and b6 in ~c"_" and is_p(b7) and is_a(b8) and is_r(b9) and is_t(b10) and is_i(b11) and is_t(b12) and is_i(b13) and is_o(b14) and is_n(b15), do: {:reserved, :begin_partition} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_b(b1) and is_e(b2) and is_t(b3) and is_w(b4) and is_e(b5) and is_e(b6) and is_n(b7), do: {:reserved, :between} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_b(b1) and is_i(b2) and is_g(b3) and is_i(b4) and is_n(b5) and is_t(b6), do: {:reserved, :bigint} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_b(b1) and is_i(b2) and is_n(b3) and is_a(b4) and is_r(b5) and is_y(b6), do: {:reserved, :binary} - + def tag([[[[[], b1], b2], b3], b4]) when is_b(b1) and is_l(b2) and is_o(b3) and is_b(b4), do: {:reserved, :blob} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_b(b1) and is_o(b2) and is_o(b3) and is_l(b4) and is_e(b5) and is_a(b6) and is_n(b7), do: {:reserved, :boolean} - + def tag([[[[[], b1], b2], b3], b4]) when is_b(b1) and is_o(b2) and is_t(b3) and is_h(b4), do: {:reserved, :both} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_b(b1) and is_t(b2) and is_r(b3) and is_i(b4) and is_m(b5), do: {:reserved, :btrim} - + def tag([[[], b1], b2]) when is_b(b1) and is_y(b2), do: {:reserved, :by} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_a(b2) and is_l(b3) and is_l(b4), do: {:reserved, :call} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_c(b1) and is_a(b2) and is_l(b3) and is_l(b4) and is_e(b5) and is_d(b6), do: {:reserved, :called} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_a(b2) and is_r(b3) and is_d(b4) and is_i(b5) and is_n(b6) and is_a(b7) and is_l(b8) and is_i(b9) and is_t(b10) and is_y(b11), do: {:reserved, :cardinality} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_c(b1) and is_a(b2) and is_s(b3) and is_c(b4) and is_a(b5) and is_d(b6) and is_e(b7) and is_d(b8), do: {:reserved, :cascaded} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_a(b2) and is_s(b3) and is_e(b4), do: {:reserved, :case} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_a(b2) and is_s(b3) and is_t(b4), do: {:reserved, :cast} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_e(b2) and is_i(b3) and is_l(b4), do: {:reserved, :ceil} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_e(b2) and is_i(b3) and is_l(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:reserved, :ceiling} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4), do: {:reserved, :char} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and b5 in ~c"_" and is_l(b6) and is_e(b7) and is_n(b8) and is_g(b9) and is_t(b10) and is_h(b11), do: {:reserved, :char_length} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9), do: {:reserved, :character} - + def tag([[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_l(b11) and is_e(b12) and is_n(b13) and is_g(b14) and is_t(b15) and is_h(b16), do: {:reserved, :character_length} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_h(b2) and is_e(b3) and is_c(b4) and is_k(b5), do: {:reserved, :check} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_c(b1) and is_l(b2) and is_a(b3) and is_s(b4) and is_s(b5) and is_i(b6) and is_f(b7) and is_i(b8) and is_e(b9) and is_r(b10), do: {:reserved, :classifier} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_l(b2) and is_o(b3) and is_b(b4), do: {:reserved, :clob} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_l(b2) and is_o(b3) and is_s(b4) and is_e(b5), do: {:reserved, :close} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_c(b1) and is_o(b2) and is_a(b3) and is_l(b4) and is_e(b5) and is_s(b6) and is_c(b7) and is_e(b8), do: {:reserved, :coalesce} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_a(b5) and is_t(b6) and is_e(b7), do: {:reserved, :collate} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_e(b5) and is_c(b6) and is_t(b7), do: {:reserved, :collect} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_c(b1) and is_o(b2) and is_l(b3) and is_u(b4) and is_m(b5) and is_n(b6), do: {:reserved, :column} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_c(b1) and is_o(b2) and is_m(b3) and is_m(b4) and is_i(b5) and is_t(b6), do: {:reserved, :commit} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_c(b1) and is_o(b2) and is_n(b3) and is_d(b4) and is_i(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9), do: {:reserved, :condition} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_o(b2) and is_n(b3) and is_n(b4) and is_e(b5) and is_c(b6) and is_t(b7), do: {:reserved, :connect} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_c(b1) and is_o(b2) and is_n(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_a(b7) and is_i(b8) and is_n(b9) and is_t(b10), do: {:reserved, :constraint} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_c(b1) and is_o(b2) and is_n(b3) and is_t(b4) and is_a(b5) and is_i(b6) and is_n(b7) and is_s(b8), do: {:reserved, :contains} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_o(b2) and is_n(b3) and is_v(b4) and is_e(b5) and is_r(b6) and is_t(b7), do: {:reserved, :convert} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_o(b2) and is_p(b3) and is_y(b4), do: {:reserved, :copy} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_o(b2) and is_r(b3) and is_r(b4), do: {:reserved, :corr} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_c(b1) and is_o(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_s(b6) and is_p(b7) and is_o(b8) and is_n(b9) and is_d(b10) and is_i(b11) and is_n(b12) and is_g(b13), do: {:reserved, :corresponding} - + def tag([[[[], b1], b2], b3]) when is_c(b1) and is_o(b2) and is_s(b3), do: {:reserved, :cos} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_o(b2) and is_s(b3) and is_h(b4), do: {:reserved, :cosh} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_o(b2) and is_u(b3) and is_n(b4) and is_t(b5), do: {:reserved, :count} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_c(b1) and is_o(b2) and is_v(b3) and is_a(b4) and is_r(b5) and b6 in ~c"_" and is_p(b7) and is_o(b8) and is_p(b9), do: {:reserved, :covar_pop} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_c(b1) and is_o(b2) and is_v(b3) and is_a(b4) and is_r(b5) and b6 in ~c"_" and is_s(b7) and is_a(b8) and is_m(b9) and is_p(b10), do: {:reserved, :covar_samp} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_c(b1) and is_r(b2) and is_e(b3) and is_a(b4) and is_t(b5) and is_e(b6), do: {:reserved, :create} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_r(b2) and is_o(b3) and is_s(b4) and is_s(b5), do: {:reserved, :cross} - + def tag([[[[[], b1], b2], b3], b4]) when is_c(b1) and is_u(b2) and is_b(b3) and is_e(b4), do: {:reserved, :cube} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_c(b1) and is_u(b2) and is_m(b3) and is_e(b4) and b5 in ~c"_" and is_d(b6) and is_i(b7) and is_s(b8) and is_t(b9), do: {:reserved, :cume_dist} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7), do: {:reserved, :current} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_c(b9) and is_a(b10) and is_t(b11) and is_a(b12) and is_l(b13) and is_o(b14) and is_g(b15), do: {:reserved, :current_catalog} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_d(b9) and is_a(b10) and is_t(b11) and is_e(b12), do: {:reserved, :current_date} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25], b26], b27], b28], b29], b30], b31]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_d(b9) and is_e(b10) and is_f(b11) and is_a(b12) and is_u(b13) and is_l(b14) and is_t(b15) and b16 in ~c"_" and is_t(b17) and is_r(b18) and is_a(b19) and is_n(b20) and is_s(b21) and is_f(b22) and is_o(b23) and is_r(b24) and is_m(b25) and b26 in ~c"_" and is_g(b27) and is_r(b28) and is_o(b29) and is_u(b30) and is_p(b31), do: {:reserved, :current_default_transform_group} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_p(b9) and is_a(b10) and is_t(b11) and is_h(b12), do: {:reserved, :current_path} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_r(b9) and is_o(b10) and is_l(b11) and is_e(b12), do: {:reserved, :current_role} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_r(b9) and is_o(b10) and is_w(b11), do: {:reserved, :current_row} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_s(b9) and is_c(b10) and is_h(b11) and is_e(b12) and is_m(b13) and is_a(b14), do: {:reserved, :current_schema} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_t(b9) and is_i(b10) and is_m(b11) and is_e(b12), do: {:reserved, :current_time} - + def tag([[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_t(b9) and is_i(b10) and is_m(b11) and is_e(b12) and is_s(b13) and is_t(b14) and is_a(b15) and is_m(b16) and is_p(b17), do: {:reserved, :current_timestamp} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25], b26], b27], b28], b29], b30], b31], b32]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_t(b9) and is_r(b10) and is_a(b11) and is_n(b12) and is_s(b13) and is_f(b14) and is_o(b15) and is_r(b16) and is_m(b17) and b18 in ~c"_" and is_g(b19) and is_r(b20) and is_o(b21) and is_u(b22) and is_p(b23) and b24 in ~c"_" and is_f(b25) and is_o(b26) and is_r(b27) and b28 in ~c"_" and is_t(b29) and is_y(b30) and is_p(b31) and is_e(b32), do: {:reserved, :current_transform_group_for_type} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_u(b2) and is_r(b3) and is_r(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_u(b9) and is_s(b10) and is_e(b11) and is_r(b12), do: {:reserved, :current_user} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_c(b1) and is_u(b2) and is_r(b3) and is_s(b4) and is_o(b5) and is_r(b6), do: {:reserved, :cursor} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_y(b2) and is_c(b3) and is_l(b4) and is_e(b5), do: {:reserved, :cycle} - + def tag([[[[[], b1], b2], b3], b4]) when is_d(b1) and is_a(b2) and is_t(b3) and is_e(b4), do: {:reserved, :date} - + def tag([[[[], b1], b2], b3]) when is_d(b1) and is_a(b2) and is_y(b3), do: {:reserved, :day} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_d(b1) and is_e(b2) and is_a(b3) and is_l(b4) and is_l(b5) and is_o(b6) and is_c(b7) and is_a(b8) and is_t(b9) and is_e(b10), do: {:reserved, :deallocate} - + def tag([[[[], b1], b2], b3]) when is_d(b1) and is_e(b2) and is_c(b3), do: {:reserved, :dec} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_e(b2) and is_c(b3) and is_f(b4) and is_l(b5) and is_o(b6) and is_a(b7) and is_t(b8), do: {:reserved, :decfloat} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_e(b2) and is_c(b3) and is_i(b4) and is_m(b5) and is_a(b6) and is_l(b7), do: {:reserved, :decimal} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_e(b2) and is_c(b3) and is_l(b4) and is_a(b5) and is_r(b6) and is_e(b7), do: {:reserved, :declare} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_e(b2) and is_f(b3) and is_a(b4) and is_u(b5) and is_l(b6) and is_t(b7), do: {:reserved, :default} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_d(b1) and is_e(b2) and is_f(b3) and is_i(b4) and is_n(b5) and is_e(b6), do: {:reserved, :define} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_d(b1) and is_e(b2) and is_l(b3) and is_e(b4) and is_t(b5) and is_e(b6), do: {:reserved, :delete} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_d(b1) and is_e(b2) and is_n(b3) and is_s(b4) and is_e(b5) and b6 in ~c"_" and is_r(b7) and is_a(b8) and is_n(b9) and is_k(b10), do: {:reserved, :dense_rank} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_d(b1) and is_e(b2) and is_r(b3) and is_e(b4) and is_f(b5), do: {:reserved, :deref} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_e(b2) and is_s(b3) and is_c(b4) and is_r(b5) and is_i(b6) and is_b(b7) and is_e(b8), do: {:reserved, :describe} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_d(b1) and is_e(b2) and is_t(b3) and is_e(b4) and is_r(b5) and is_m(b6) and is_i(b7) and is_n(b8) and is_i(b9) and is_s(b10) and is_t(b11) and is_i(b12) and is_c(b13), do: {:reserved, :deterministic} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_d(b1) and is_i(b2) and is_s(b3) and is_c(b4) and is_o(b5) and is_n(b6) and is_n(b7) and is_e(b8) and is_c(b9) and is_t(b10), do: {:reserved, :disconnect} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_i(b2) and is_s(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_c(b7) and is_t(b8), do: {:reserved, :distinct} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_d(b1) and is_o(b2) and is_u(b3) and is_b(b4) and is_l(b5) and is_e(b6), do: {:reserved, :double} - + def tag([[[[[], b1], b2], b3], b4]) when is_d(b1) and is_r(b2) and is_o(b3) and is_p(b4), do: {:reserved, :drop} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_y(b2) and is_n(b3) and is_a(b4) and is_m(b5) and is_i(b6) and is_c(b7), do: {:reserved, :dynamic} - + def tag([[[[[], b1], b2], b3], b4]) when is_e(b1) and is_a(b2) and is_c(b3) and is_h(b4), do: {:reserved, :each} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_e(b1) and is_l(b2) and is_e(b3) and is_m(b4) and is_e(b5) and is_n(b6) and is_t(b7), do: {:reserved, :element} - + def tag([[[[[], b1], b2], b3], b4]) when is_e(b1) and is_l(b2) and is_s(b3) and is_e(b4), do: {:reserved, :else} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_e(b1) and is_m(b2) and is_p(b3) and is_t(b4) and is_y(b5), do: {:reserved, :empty} - + def tag([[[[], b1], b2], b3]) when is_e(b1) and is_n(b2) and is_d(b3), do: {:reserved, :end} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_e(b1) and is_n(b2) and is_d(b3) and b4 in ~c"_" and is_f(b5) and is_r(b6) and is_a(b7) and is_m(b8) and is_e(b9), do: {:reserved, :end_frame} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_e(b1) and is_n(b2) and is_d(b3) and b4 in ~c"_" and is_p(b5) and is_a(b6) and is_r(b7) and is_t(b8) and is_i(b9) and is_t(b10) and is_i(b11) and is_o(b12) and is_n(b13), do: {:reserved, :end_partition} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_e(b1) and is_n(b2) and is_d(b3) and b4 in ~c"-" and is_e(b5) and is_x(b6) and is_e(b7) and is_c(b8), do: {:reserved, :"end-exec"} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_e(b1) and is_q(b2) and is_u(b3) and is_a(b4) and is_l(b5) and is_s(b6), do: {:reserved, :equals} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_e(b1) and is_s(b2) and is_c(b3) and is_a(b4) and is_p(b5) and is_e(b6), do: {:reserved, :escape} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_e(b1) and is_v(b2) and is_e(b3) and is_r(b4) and is_y(b5), do: {:reserved, :every} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_e(b1) and is_x(b2) and is_c(b3) and is_e(b4) and is_p(b5) and is_t(b6), do: {:reserved, :except} - + def tag([[[[[], b1], b2], b3], b4]) when is_e(b1) and is_x(b2) and is_e(b3) and is_c(b4), do: {:reserved, :exec} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_e(b1) and is_x(b2) and is_e(b3) and is_c(b4) and is_u(b5) and is_t(b6) and is_e(b7), do: {:reserved, :execute} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_e(b1) and is_x(b2) and is_i(b3) and is_s(b4) and is_t(b5) and is_s(b6), do: {:reserved, :exists} - + def tag([[[[], b1], b2], b3]) when is_e(b1) and is_x(b2) and is_p(b3), do: {:reserved, :exp} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_e(b1) and is_x(b2) and is_t(b3) and is_e(b4) and is_r(b5) and is_n(b6) and is_a(b7) and is_l(b8), do: {:reserved, :external} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_e(b1) and is_x(b2) and is_t(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7), do: {:reserved, :extract} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_a(b2) and is_l(b3) and is_s(b4) and is_e(b5), do: {:reserved, false} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_e(b2) and is_t(b3) and is_c(b4) and is_h(b5), do: {:reserved, :fetch} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_f(b1) and is_i(b2) and is_l(b3) and is_t(b4) and is_e(b5) and is_r(b6), do: {:reserved, :filter} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_f(b1) and is_i(b2) and is_r(b3) and is_s(b4) and is_t(b5) and b6 in ~c"_" and is_v(b7) and is_a(b8) and is_l(b9) and is_u(b10) and is_e(b11), do: {:reserved, :first_value} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_l(b2) and is_o(b3) and is_a(b4) and is_t(b5), do: {:reserved, :float} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_l(b2) and is_o(b3) and is_o(b4) and is_r(b5), do: {:reserved, :floor} - + def tag([[[[], b1], b2], b3]) when is_f(b1) and is_o(b2) and is_r(b3), do: {:reserved, :for} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_f(b1) and is_o(b2) and is_r(b3) and is_e(b4) and is_i(b5) and is_g(b6) and is_n(b7), do: {:reserved, :foreign} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_f(b1) and is_r(b2) and is_a(b3) and is_m(b4) and is_e(b5) and b6 in ~c"_" and is_r(b7) and is_o(b8) and is_w(b9), do: {:reserved, :frame_row} - + def tag([[[[[], b1], b2], b3], b4]) when is_f(b1) and is_r(b2) and is_e(b3) and is_e(b4), do: {:reserved, :free} - + def tag([[[[[], b1], b2], b3], b4]) when is_f(b1) and is_r(b2) and is_o(b3) and is_m(b4), do: {:reserved, :from} - + def tag([[[[[], b1], b2], b3], b4]) when is_f(b1) and is_u(b2) and is_l(b3) and is_l(b4), do: {:reserved, :full} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_f(b1) and is_u(b2) and is_n(b3) and is_c(b4) and is_t(b5) and is_i(b6) and is_o(b7) and is_n(b8), do: {:reserved, :function} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_f(b1) and is_u(b2) and is_s(b3) and is_i(b4) and is_o(b5) and is_n(b6), do: {:reserved, :fusion} - + def tag([[[[], b1], b2], b3]) when is_g(b1) and is_e(b2) and is_t(b3), do: {:reserved, :get} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_g(b1) and is_l(b2) and is_o(b3) and is_b(b4) and is_a(b5) and is_l(b6), do: {:reserved, :global} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_g(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_t(b5), do: {:reserved, :grant} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_g(b1) and is_r(b2) and is_e(b3) and is_a(b4) and is_t(b5) and is_e(b6) and is_s(b7) and is_t(b8), do: {:reserved, :greatest} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_g(b1) and is_r(b2) and is_o(b3) and is_u(b4) and is_p(b5), do: {:reserved, :group} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_g(b1) and is_r(b2) and is_o(b3) and is_u(b4) and is_p(b5) and is_i(b6) and is_n(b7) and is_g(b8), do: {:reserved, :grouping} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_g(b1) and is_r(b2) and is_o(b3) and is_u(b4) and is_p(b5) and is_s(b6), do: {:reserved, :groups} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_h(b1) and is_a(b2) and is_v(b3) and is_i(b4) and is_n(b5) and is_g(b6), do: {:reserved, :having} - + def tag([[[[[], b1], b2], b3], b4]) when is_h(b1) and is_o(b2) and is_l(b3) and is_d(b4), do: {:reserved, :hold} - + def tag([[[[[], b1], b2], b3], b4]) when is_h(b1) and is_o(b2) and is_u(b3) and is_r(b4), do: {:reserved, :hour} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_i(b1) and is_d(b2) and is_e(b3) and is_n(b4) and is_t(b5) and is_i(b6) and is_t(b7) and is_y(b8), do: {:reserved, :identity} - + def tag([[[], b1], b2]) when is_i(b1) and is_n(b2), do: {:reserved, :in} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_n(b2) and is_d(b3) and is_i(b4) and is_c(b5) and is_a(b6) and is_t(b7) and is_o(b8) and is_r(b9), do: {:reserved, :indicator} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_i(b1) and is_n(b2) and is_i(b3) and is_t(b4) and is_i(b5) and is_a(b6) and is_l(b7), do: {:reserved, :initial} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_i(b1) and is_n(b2) and is_n(b3) and is_e(b4) and is_r(b5), do: {:reserved, :inner} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_i(b1) and is_n(b2) and is_o(b3) and is_u(b4) and is_t(b5), do: {:reserved, :inout} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_i(b1) and is_n(b2) and is_s(b3) and is_e(b4) and is_n(b5) and is_s(b6) and is_i(b7) and is_t(b8) and is_i(b9) and is_v(b10) and is_e(b11), do: {:reserved, :insensitive} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_i(b1) and is_n(b2) and is_s(b3) and is_e(b4) and is_r(b5) and is_t(b6), do: {:reserved, :insert} - + def tag([[[[], b1], b2], b3]) when is_i(b1) and is_n(b2) and is_t(b3), do: {:reserved, :int} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_i(b1) and is_n(b2) and is_t(b3) and is_e(b4) and is_g(b5) and is_e(b6) and is_r(b7), do: {:reserved, :integer} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_n(b2) and is_t(b3) and is_e(b4) and is_r(b5) and is_s(b6) and is_e(b7) and is_c(b8) and is_t(b9), do: {:reserved, :intersect} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_i(b1) and is_n(b2) and is_t(b3) and is_e(b4) and is_r(b5) and is_s(b6) and is_e(b7) and is_c(b8) and is_t(b9) and is_i(b10) and is_o(b11) and is_n(b12), do: {:reserved, :intersection} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_i(b1) and is_n(b2) and is_t(b3) and is_e(b4) and is_r(b5) and is_v(b6) and is_a(b7) and is_l(b8), do: {:reserved, :interval} - + def tag([[[[[], b1], b2], b3], b4]) when is_i(b1) and is_n(b2) and is_t(b3) and is_o(b4), do: {:reserved, :into} - + def tag([[[], b1], b2]) when is_i(b1) and is_s(b2), do: {:reserved, :is} - + def tag([[[[[], b1], b2], b3], b4]) when is_j(b1) and is_o(b2) and is_i(b3) and is_n(b4), do: {:reserved, :join} - + def tag([[[[[], b1], b2], b3], b4]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4), do: {:reserved, :json} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_a(b6) and is_r(b7) and is_r(b8) and is_a(b9) and is_y(b10), do: {:reserved, :json_array} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_a(b6) and is_r(b7) and is_r(b8) and is_a(b9) and is_y(b10) and is_a(b11) and is_g(b12) and is_g(b13), do: {:reserved, :json_arrayagg} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_e(b6) and is_x(b7) and is_i(b8) and is_s(b9) and is_t(b10) and is_s(b11), do: {:reserved, :json_exists} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_o(b6) and is_b(b7) and is_j(b8) and is_e(b9) and is_c(b10) and is_t(b11), do: {:reserved, :json_object} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_o(b6) and is_b(b7) and is_j(b8) and is_e(b9) and is_c(b10) and is_t(b11) and is_a(b12) and is_g(b13) and is_g(b14), do: {:reserved, :json_objectagg} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_q(b6) and is_u(b7) and is_e(b8) and is_r(b9) and is_y(b10), do: {:reserved, :json_query} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_s(b6) and is_c(b7) and is_a(b8) and is_l(b9) and is_a(b10) and is_r(b11), do: {:reserved, :json_scalar} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_s(b6) and is_e(b7) and is_r(b8) and is_i(b9) and is_a(b10) and is_l(b11) and is_i(b12) and is_z(b13) and is_e(b14), do: {:reserved, :json_serialize} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_t(b6) and is_a(b7) and is_b(b8) and is_l(b9) and is_e(b10), do: {:reserved, :json_table} - + def tag([[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_t(b6) and is_a(b7) and is_b(b8) and is_l(b9) and is_e(b10) and b11 in ~c"_" and is_p(b12) and is_r(b13) and is_i(b14) and is_m(b15) and is_i(b16) and is_t(b17) and is_i(b18) and is_v(b19) and is_e(b20), do: {:reserved, :json_table_primitive} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_j(b1) and is_s(b2) and is_o(b3) and is_n(b4) and b5 in ~c"_" and is_v(b6) and is_a(b7) and is_l(b8) and is_u(b9) and is_e(b10), do: {:reserved, :json_value} - + def tag([[[[], b1], b2], b3]) when is_l(b1) and is_a(b2) and is_g(b3), do: {:reserved, :lag} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_l(b1) and is_a(b2) and is_n(b3) and is_g(b4) and is_u(b5) and is_a(b6) and is_g(b7) and is_e(b8), do: {:reserved, :language} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_a(b2) and is_r(b3) and is_g(b4) and is_e(b5), do: {:reserved, :large} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_l(b1) and is_a(b2) and is_s(b3) and is_t(b4) and b5 in ~c"_" and is_v(b6) and is_a(b7) and is_l(b8) and is_u(b9) and is_e(b10), do: {:reserved, :last_value} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_l(b1) and is_a(b2) and is_t(b3) and is_e(b4) and is_r(b5) and is_a(b6) and is_l(b7), do: {:reserved, :lateral} - + def tag([[[[[], b1], b2], b3], b4]) when is_l(b1) and is_e(b2) and is_a(b3) and is_d(b4), do: {:reserved, :lead} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_l(b1) and is_e(b2) and is_a(b3) and is_d(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:reserved, :leading} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_e(b2) and is_a(b3) and is_s(b4) and is_t(b5), do: {:reserved, :least} - + def tag([[[[[], b1], b2], b3], b4]) when is_l(b1) and is_e(b2) and is_f(b3) and is_t(b4), do: {:reserved, :left} - + def tag([[[[[], b1], b2], b3], b4]) when is_l(b1) and is_i(b2) and is_k(b3) and is_e(b4), do: {:reserved, :like} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_l(b1) and is_i(b2) and is_k(b3) and is_e(b4) and b5 in ~c"_" and is_r(b6) and is_e(b7) and is_g(b8) and is_e(b9) and is_x(b10), do: {:reserved, :like_regex} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_l(b1) and is_i(b2) and is_s(b3) and is_t(b4) and is_a(b5) and is_g(b6) and is_g(b7), do: {:reserved, :listagg} - + def tag([[[], b1], b2]) when is_l(b1) and is_n(b2), do: {:reserved, :ln} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_o(b2) and is_c(b3) and is_a(b4) and is_l(b5), do: {:reserved, :local} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_l(b1) and is_o(b2) and is_c(b3) and is_a(b4) and is_l(b5) and is_t(b6) and is_i(b7) and is_m(b8) and is_e(b9), do: {:reserved, :localtime} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_l(b1) and is_o(b2) and is_c(b3) and is_a(b4) and is_l(b5) and is_t(b6) and is_i(b7) and is_m(b8) and is_e(b9) and is_s(b10) and is_t(b11) and is_a(b12) and is_m(b13) and is_p(b14), do: {:reserved, :localtimestamp} - + def tag([[[[], b1], b2], b3]) when is_l(b1) and is_o(b2) and is_g(b3), do: {:reserved, :log} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_o(b2) and is_g(b3) and b4 in ~c"1" and b5 in ~c"0", do: {:reserved, :log10} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_o(b2) and is_w(b3) and is_e(b4) and is_r(b5), do: {:reserved, :lower} - + def tag([[[[[], b1], b2], b3], b4]) when is_l(b1) and is_p(b2) and is_a(b3) and is_d(b4), do: {:reserved, :lpad} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_t(b2) and is_r(b3) and is_i(b4) and is_m(b5), do: {:reserved, :ltrim} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_m(b1) and is_a(b2) and is_t(b3) and is_c(b4) and is_h(b5), do: {:reserved, :match} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_m(b1) and is_a(b2) and is_t(b3) and is_c(b4) and is_h(b5) and b6 in ~c"_" and is_n(b7) and is_u(b8) and is_m(b9) and is_b(b10) and is_e(b11) and is_r(b12), do: {:reserved, :match_number} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_m(b1) and is_a(b2) and is_t(b3) and is_c(b4) and is_h(b5) and b6 in ~c"_" and is_r(b7) and is_e(b8) and is_c(b9) and is_o(b10) and is_g(b11) and is_n(b12) and is_i(b13) and is_z(b14) and is_e(b15), do: {:reserved, :match_recognize} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_m(b1) and is_a(b2) and is_t(b3) and is_c(b4) and is_h(b5) and is_e(b6) and is_s(b7), do: {:reserved, :matches} - + def tag([[[[], b1], b2], b3]) when is_m(b1) and is_a(b2) and is_x(b3), do: {:reserved, :max} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_m(b1) and is_e(b2) and is_m(b3) and is_b(b4) and is_e(b5) and is_r(b6), do: {:reserved, :member} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_m(b1) and is_e(b2) and is_r(b3) and is_g(b4) and is_e(b5), do: {:reserved, :merge} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_m(b1) and is_e(b2) and is_t(b3) and is_h(b4) and is_o(b5) and is_d(b6), do: {:reserved, :method} - + def tag([[[[], b1], b2], b3]) when is_m(b1) and is_i(b2) and is_n(b3), do: {:reserved, :min} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_m(b1) and is_i(b2) and is_n(b3) and is_u(b4) and is_t(b5) and is_e(b6), do: {:reserved, :minute} - + def tag([[[[], b1], b2], b3]) when is_m(b1) and is_o(b2) and is_d(b3), do: {:reserved, :mod} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_m(b1) and is_o(b2) and is_d(b3) and is_i(b4) and is_f(b5) and is_i(b6) and is_e(b7) and is_s(b8), do: {:reserved, :modifies} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_m(b1) and is_o(b2) and is_d(b3) and is_u(b4) and is_l(b5) and is_e(b6), do: {:reserved, :module} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_m(b1) and is_o(b2) and is_n(b3) and is_t(b4) and is_h(b5), do: {:reserved, :month} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_m(b1) and is_u(b2) and is_l(b3) and is_t(b4) and is_i(b5) and is_s(b6) and is_e(b7) and is_t(b8), do: {:reserved, :multiset} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_n(b1) and is_a(b2) and is_t(b3) and is_i(b4) and is_o(b5) and is_n(b6) and is_a(b7) and is_l(b8), do: {:reserved, :national} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_n(b1) and is_a(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_a(b6) and is_l(b7), do: {:reserved, :natural} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_n(b1) and is_c(b2) and is_h(b3) and is_a(b4) and is_r(b5), do: {:reserved, :nchar} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_n(b1) and is_c(b2) and is_l(b3) and is_o(b4) and is_b(b5), do: {:reserved, :nclob} - + def tag([[[[], b1], b2], b3]) when is_n(b1) and is_e(b2) and is_w(b3), do: {:reserved, :new} - + def tag([[[], b1], b2]) when is_n(b1) and is_o(b2), do: {:reserved, :no} - + def tag([[[[[], b1], b2], b3], b4]) when is_n(b1) and is_o(b2) and is_n(b3) and is_e(b4), do: {:reserved, :none} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_n(b1) and is_o(b2) and is_r(b3) and is_m(b4) and is_a(b5) and is_l(b6) and is_i(b7) and is_z(b8) and is_e(b9), do: {:reserved, :normalize} - + def tag([[[[], b1], b2], b3]) when is_n(b1) and is_o(b2) and is_t(b3), do: {:reserved, :not} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_n(b1) and is_t(b2) and is_h(b3) and b4 in ~c"_" and is_v(b5) and is_a(b6) and is_l(b7) and is_u(b8) and is_e(b9), do: {:reserved, :nth_value} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_n(b1) and is_t(b2) and is_i(b3) and is_l(b4) and is_e(b5), do: {:reserved, :ntile} - + def tag([[[[[], b1], b2], b3], b4]) when is_n(b1) and is_u(b2) and is_l(b3) and is_l(b4), do: {:reserved, :null} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_n(b1) and is_u(b2) and is_l(b3) and is_l(b4) and is_i(b5) and is_f(b6), do: {:reserved, :nullif} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_n(b1) and is_u(b2) and is_m(b3) and is_e(b4) and is_r(b5) and is_i(b6) and is_c(b7), do: {:reserved, :numeric} - + def tag([[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17]) when is_o(b1) and is_c(b2) and is_c(b3) and is_u(b4) and is_r(b5) and is_r(b6) and is_e(b7) and is_n(b8) and is_c(b9) and is_e(b10) and is_s(b11) and b12 in ~c"_" and is_r(b13) and is_e(b14) and is_g(b15) and is_e(b16) and is_x(b17), do: {:reserved, :occurrences_regex} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_o(b1) and is_c(b2) and is_t(b3) and is_e(b4) and is_t(b5) and b6 in ~c"_" and is_l(b7) and is_e(b8) and is_n(b9) and is_g(b10) and is_t(b11) and is_h(b12), do: {:reserved, :octet_length} - + def tag([[[], b1], b2]) when is_o(b1) and is_f(b2), do: {:reserved, :of} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_o(b1) and is_f(b2) and is_f(b3) and is_s(b4) and is_e(b5) and is_t(b6), do: {:reserved, :offset} - + def tag([[[[], b1], b2], b3]) when is_o(b1) and is_l(b2) and is_d(b3), do: {:reserved, :old} - + def tag([[[[[], b1], b2], b3], b4]) when is_o(b1) and is_m(b2) and is_i(b3) and is_t(b4), do: {:reserved, :omit} - + def tag([[[], b1], b2]) when is_o(b1) and is_n(b2), do: {:reserved, :on} - + def tag([[[[], b1], b2], b3]) when is_o(b1) and is_n(b2) and is_e(b3), do: {:reserved, :one} - + def tag([[[[[], b1], b2], b3], b4]) when is_o(b1) and is_n(b2) and is_l(b3) and is_y(b4), do: {:reserved, :only} - + def tag([[[[[], b1], b2], b3], b4]) when is_o(b1) and is_p(b2) and is_e(b3) and is_n(b4), do: {:reserved, :open} - + def tag([[[], b1], b2]) when is_o(b1) and is_r(b2), do: {:reserved, :or} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_o(b1) and is_r(b2) and is_d(b3) and is_e(b4) and is_r(b5), do: {:reserved, :order} - + def tag([[[[], b1], b2], b3]) when is_o(b1) and is_u(b2) and is_t(b3), do: {:reserved, :out} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_o(b1) and is_u(b2) and is_t(b3) and is_e(b4) and is_r(b5), do: {:reserved, :outer} - + def tag([[[[[], b1], b2], b3], b4]) when is_o(b1) and is_v(b2) and is_e(b3) and is_r(b4), do: {:reserved, :over} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_o(b1) and is_v(b2) and is_e(b3) and is_r(b4) and is_l(b5) and is_a(b6) and is_p(b7) and is_s(b8), do: {:reserved, :overlaps} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_o(b1) and is_v(b2) and is_e(b3) and is_r(b4) and is_l(b5) and is_a(b6) and is_y(b7), do: {:reserved, :overlay} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9), do: {:reserved, :parameter} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_p(b1) and is_a(b2) and is_r(b3) and is_t(b4) and is_i(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9), do: {:reserved, :partition} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_a(b2) and is_t(b3) and is_t(b4) and is_e(b5) and is_r(b6) and is_n(b7), do: {:reserved, :pattern} - + def tag([[[[], b1], b2], b3]) when is_p(b1) and is_e(b2) and is_r(b3), do: {:reserved, :per} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_e(b2) and is_r(b3) and is_c(b4) and is_e(b5) and is_n(b6) and is_t(b7), do: {:reserved, :percent} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_p(b1) and is_e(b2) and is_r(b3) and is_c(b4) and is_e(b5) and is_n(b6) and is_t(b7) and b8 in ~c"_" and is_r(b9) and is_a(b10) and is_n(b11) and is_k(b12), do: {:reserved, :percent_rank} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_p(b1) and is_e(b2) and is_r(b3) and is_c(b4) and is_e(b5) and is_n(b6) and is_t(b7) and is_i(b8) and is_l(b9) and is_e(b10) and b11 in ~c"_" and is_c(b12) and is_o(b13) and is_n(b14) and is_t(b15), do: {:reserved, :percentile_cont} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_p(b1) and is_e(b2) and is_r(b3) and is_c(b4) and is_e(b5) and is_n(b6) and is_t(b7) and is_i(b8) and is_l(b9) and is_e(b10) and b11 in ~c"_" and is_d(b12) and is_i(b13) and is_s(b14) and is_c(b15), do: {:reserved, :percentile_disc} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_p(b1) and is_e(b2) and is_r(b3) and is_i(b4) and is_o(b5) and is_d(b6), do: {:reserved, :period} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_o(b2) and is_r(b3) and is_t(b4) and is_i(b5) and is_o(b6) and is_n(b7), do: {:reserved, :portion} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_p(b1) and is_o(b2) and is_s(b3) and is_i(b4) and is_t(b5) and is_i(b6) and is_o(b7) and is_n(b8), do: {:reserved, :position} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_p(b1) and is_o(b2) and is_s(b3) and is_i(b4) and is_t(b5) and is_i(b6) and is_o(b7) and is_n(b8) and b9 in ~c"_" and is_r(b10) and is_e(b11) and is_g(b12) and is_e(b13) and is_x(b14), do: {:reserved, :position_regex} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_p(b1) and is_o(b2) and is_w(b3) and is_e(b4) and is_r(b5), do: {:reserved, :power} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_p(b1) and is_r(b2) and is_e(b3) and is_c(b4) and is_e(b5) and is_d(b6) and is_e(b7) and is_s(b8), do: {:reserved, :precedes} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_p(b1) and is_r(b2) and is_e(b3) and is_c(b4) and is_i(b5) and is_s(b6) and is_i(b7) and is_o(b8) and is_n(b9), do: {:reserved, :precision} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_r(b2) and is_e(b3) and is_p(b4) and is_a(b5) and is_r(b6) and is_e(b7), do: {:reserved, :prepare} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_r(b2) and is_i(b3) and is_m(b4) and is_a(b5) and is_r(b6) and is_y(b7), do: {:reserved, :primary} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_p(b1) and is_r(b2) and is_o(b3) and is_c(b4) and is_e(b5) and is_d(b6) and is_u(b7) and is_r(b8) and is_e(b9), do: {:reserved, :procedure} - + def tag([[[[], b1], b2], b3]) when is_p(b1) and is_t(b2) and is_f(b3), do: {:reserved, :ptf} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_r(b1) and is_a(b2) and is_n(b3) and is_g(b4) and is_e(b5), do: {:reserved, :range} - + def tag([[[[[], b1], b2], b3], b4]) when is_r(b1) and is_a(b2) and is_n(b3) and is_k(b4), do: {:reserved, :rank} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_r(b1) and is_e(b2) and is_a(b3) and is_d(b4) and is_s(b5), do: {:reserved, :reads} - + def tag([[[[[], b1], b2], b3], b4]) when is_r(b1) and is_e(b2) and is_a(b3) and is_l(b4), do: {:reserved, :real} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_r(b1) and is_e(b2) and is_c(b3) and is_u(b4) and is_r(b5) and is_s(b6) and is_i(b7) and is_v(b8) and is_e(b9), do: {:reserved, :recursive} - + def tag([[[[], b1], b2], b3]) when is_r(b1) and is_e(b2) and is_f(b3), do: {:reserved, :ref} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_r(b1) and is_e(b2) and is_f(b3) and is_e(b4) and is_r(b5) and is_e(b6) and is_n(b7) and is_c(b8) and is_e(b9) and is_s(b10), do: {:reserved, :references} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_r(b1) and is_e(b2) and is_f(b3) and is_e(b4) and is_r(b5) and is_e(b6) and is_n(b7) and is_c(b8) and is_i(b9) and is_n(b10) and is_g(b11), do: {:reserved, :referencing} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_a(b6) and is_v(b7) and is_g(b8) and is_x(b9), do: {:reserved, :regr_avgx} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_a(b6) and is_v(b7) and is_g(b8) and is_y(b9), do: {:reserved, :regr_avgy} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_c(b6) and is_o(b7) and is_u(b8) and is_n(b9) and is_t(b10), do: {:reserved, :regr_count} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_i(b6) and is_n(b7) and is_t(b8) and is_e(b9) and is_r(b10) and is_c(b11) and is_e(b12) and is_p(b13) and is_t(b14), do: {:reserved, :regr_intercept} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_r(b6) and b7 in ~c"2", do: {:reserved, :regr_r2} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_s(b6) and is_l(b7) and is_o(b8) and is_p(b9) and is_e(b10), do: {:reserved, :regr_slope} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_s(b6) and is_x(b7) and is_x(b8), do: {:reserved, :regr_sxx} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_s(b6) and is_x(b7) and is_y(b8), do: {:reserved, :regr_sxy} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_r(b1) and is_e(b2) and is_g(b3) and is_r(b4) and b5 in ~c"_" and is_s(b6) and is_y(b7) and is_y(b8), do: {:reserved, :regr_syy} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_e(b2) and is_l(b3) and is_e(b4) and is_a(b5) and is_s(b6) and is_e(b7), do: {:reserved, :release} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_r(b1) and is_e(b2) and is_s(b3) and is_u(b4) and is_l(b5) and is_t(b6), do: {:reserved, :result} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6), do: {:reserved, :return} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6) and is_s(b7), do: {:reserved, :returns} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_r(b1) and is_e(b2) and is_v(b3) and is_o(b4) and is_k(b5) and is_e(b6), do: {:reserved, :revoke} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_r(b1) and is_i(b2) and is_g(b3) and is_h(b4) and is_t(b5), do: {:reserved, :right} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_r(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_b(b5) and is_a(b6) and is_c(b7) and is_k(b8), do: {:reserved, :rollback} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_r(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_u(b5) and is_p(b6), do: {:reserved, :rollup} - + def tag([[[[], b1], b2], b3]) when is_r(b1) and is_o(b2) and is_w(b3), do: {:reserved, :row} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_r(b1) and is_o(b2) and is_w(b3) and b4 in ~c"_" and is_n(b5) and is_u(b6) and is_m(b7) and is_b(b8) and is_e(b9) and is_r(b10), do: {:reserved, :row_number} - + def tag([[[[[], b1], b2], b3], b4]) when is_r(b1) and is_o(b2) and is_w(b3) and is_s(b4), do: {:reserved, :rows} - + def tag([[[[[], b1], b2], b3], b4]) when is_r(b1) and is_p(b2) and is_a(b3) and is_d(b4), do: {:reserved, :rpad} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_r(b1) and is_t(b2) and is_r(b3) and is_i(b4) and is_m(b5), do: {:reserved, :rtrim} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_u(b2) and is_n(b3) and is_n(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:reserved, :running} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_a(b2) and is_v(b3) and is_e(b4) and is_p(b5) and is_o(b6) and is_i(b7) and is_n(b8) and is_t(b9), do: {:reserved, :savepoint} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_s(b1) and is_c(b2) and is_o(b3) and is_p(b4) and is_e(b5), do: {:reserved, :scope} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_c(b2) and is_r(b3) and is_o(b4) and is_l(b5) and is_l(b6), do: {:reserved, :scroll} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_e(b2) and is_a(b3) and is_r(b4) and is_c(b5) and is_h(b6), do: {:reserved, :search} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_e(b2) and is_c(b3) and is_o(b4) and is_n(b5) and is_d(b6), do: {:reserved, :second} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_e(b2) and is_e(b3) and is_k(b4), do: {:reserved, :seek} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_e(b2) and is_l(b3) and is_e(b4) and is_c(b5) and is_t(b6), do: {:reserved, :select} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_e(b2) and is_n(b3) and is_s(b4) and is_i(b5) and is_t(b6) and is_i(b7) and is_v(b8) and is_e(b9), do: {:reserved, :sensitive} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_s(b1) and is_e(b2) and is_s(b3) and is_s(b4) and is_i(b5) and is_o(b6) and is_n(b7) and b8 in ~c"_" and is_u(b9) and is_s(b10) and is_e(b11) and is_r(b12), do: {:reserved, :session_user} - + def tag([[[[], b1], b2], b3]) when is_s(b1) and is_e(b2) and is_t(b3), do: {:reserved, :set} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_h(b2) and is_o(b3) and is_w(b4), do: {:reserved, :show} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_s(b1) and is_i(b2) and is_m(b3) and is_i(b4) and is_l(b5) and is_a(b6) and is_r(b7), do: {:reserved, :similar} - + def tag([[[[], b1], b2], b3]) when is_s(b1) and is_i(b2) and is_n(b3), do: {:reserved, :sin} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_i(b2) and is_n(b3) and is_h(b4), do: {:reserved, :sinh} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_k(b2) and is_i(b3) and is_p(b4), do: {:reserved, :skip} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_s(b1) and is_m(b2) and is_a(b3) and is_l(b4) and is_l(b5) and is_i(b6) and is_n(b7) and is_t(b8), do: {:reserved, :smallint} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_o(b2) and is_m(b3) and is_e(b4), do: {:reserved, :some} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_s(b1) and is_p(b2) and is_e(b3) and is_c(b4) and is_i(b5) and is_f(b6) and is_i(b7) and is_c(b8), do: {:reserved, :specific} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_s(b1) and is_p(b2) and is_e(b3) and is_c(b4) and is_i(b5) and is_f(b6) and is_i(b7) and is_c(b8) and is_t(b9) and is_y(b10) and is_p(b11) and is_e(b12), do: {:reserved, :specifictype} - + def tag([[[[], b1], b2], b3]) when is_s(b1) and is_q(b2) and is_l(b3), do: {:reserved, :sql} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_s(b1) and is_q(b2) and is_l(b3) and is_e(b4) and is_x(b5) and is_c(b6) and is_e(b7) and is_p(b8) and is_t(b9) and is_i(b10) and is_o(b11) and is_n(b12), do: {:reserved, :sqlexception} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_s(b1) and is_q(b2) and is_l(b3) and is_s(b4) and is_t(b5) and is_a(b6) and is_t(b7) and is_e(b8), do: {:reserved, :sqlstate} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_s(b1) and is_q(b2) and is_l(b3) and is_w(b4) and is_a(b5) and is_r(b6) and is_n(b7) and is_i(b8) and is_n(b9) and is_g(b10), do: {:reserved, :sqlwarning} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_q(b2) and is_r(b3) and is_t(b4), do: {:reserved, :sqrt} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_s(b1) and is_t(b2) and is_a(b3) and is_r(b4) and is_t(b5), do: {:reserved, :start} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_t(b2) and is_a(b3) and is_t(b4) and is_i(b5) and is_c(b6), do: {:reserved, :static} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_s(b1) and is_t(b2) and is_d(b3) and is_d(b4) and is_e(b5) and is_v(b6) and b7 in ~c"_" and is_p(b8) and is_o(b9) and is_p(b10), do: {:reserved, :stddev_pop} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_s(b1) and is_t(b2) and is_d(b3) and is_d(b4) and is_e(b5) and is_v(b6) and b7 in ~c"_" and is_s(b8) and is_a(b9) and is_m(b10) and is_p(b11), do: {:reserved, :stddev_samp} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_s(b1) and is_u(b2) and is_b(b3) and is_m(b4) and is_u(b5) and is_l(b6) and is_t(b7) and is_i(b8) and is_s(b9) and is_e(b10) and is_t(b11), do: {:reserved, :submultiset} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_u(b2) and is_b(b3) and is_s(b4) and is_e(b5) and is_t(b6), do: {:reserved, :subset} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_u(b2) and is_b(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_i(b7) and is_n(b8) and is_g(b9), do: {:reserved, :substring} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_s(b1) and is_u(b2) and is_b(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_i(b7) and is_n(b8) and is_g(b9) and b10 in ~c"_" and is_r(b11) and is_e(b12) and is_g(b13) and is_e(b14) and is_x(b15), do: {:reserved, :substring_regex} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_s(b1) and is_u(b2) and is_c(b3) and is_c(b4) and is_e(b5) and is_e(b6) and is_d(b7) and is_s(b8), do: {:reserved, :succeeds} - + def tag([[[[], b1], b2], b3]) when is_s(b1) and is_u(b2) and is_m(b3), do: {:reserved, :sum} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_y(b2) and is_m(b3) and is_m(b4) and is_e(b5) and is_t(b6) and is_r(b7) and is_i(b8) and is_c(b9), do: {:reserved, :symmetric} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_y(b2) and is_s(b3) and is_t(b4) and is_e(b5) and is_m(b6), do: {:reserved, :system} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_s(b1) and is_y(b2) and is_s(b3) and is_t(b4) and is_e(b5) and is_m(b6) and b7 in ~c"_" and is_t(b8) and is_i(b9) and is_m(b10) and is_e(b11), do: {:reserved, :system_time} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_s(b1) and is_y(b2) and is_s(b3) and is_t(b4) and is_e(b5) and is_m(b6) and b7 in ~c"_" and is_u(b8) and is_s(b9) and is_e(b10) and is_r(b11), do: {:reserved, :system_user} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_t(b1) and is_a(b2) and is_b(b3) and is_l(b4) and is_e(b5), do: {:reserved, :table} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_t(b1) and is_a(b2) and is_b(b3) and is_l(b4) and is_e(b5) and is_s(b6) and is_a(b7) and is_m(b8) and is_p(b9) and is_l(b10) and is_e(b11), do: {:reserved, :tablesample} - + def tag([[[[], b1], b2], b3]) when is_t(b1) and is_a(b2) and is_n(b3), do: {:reserved, :tan} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_a(b2) and is_n(b3) and is_h(b4), do: {:reserved, :tanh} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_h(b2) and is_e(b3) and is_n(b4), do: {:reserved, :then} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_i(b2) and is_m(b3) and is_e(b4), do: {:reserved, :time} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_t(b1) and is_i(b2) and is_m(b3) and is_e(b4) and is_s(b5) and is_t(b6) and is_a(b7) and is_m(b8) and is_p(b9), do: {:reserved, :timestamp} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_t(b1) and is_i(b2) and is_m(b3) and is_e(b4) and is_z(b5) and is_o(b6) and is_n(b7) and is_e(b8) and b9 in ~c"_" and is_h(b10) and is_o(b11) and is_u(b12) and is_r(b13), do: {:reserved, :timezone_hour} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_t(b1) and is_i(b2) and is_m(b3) and is_e(b4) and is_z(b5) and is_o(b6) and is_n(b7) and is_e(b8) and b9 in ~c"_" and is_m(b10) and is_i(b11) and is_n(b12) and is_u(b13) and is_t(b14) and is_e(b15), do: {:reserved, :timezone_minute} - + def tag([[[], b1], b2]) when is_t(b1) and is_o(b2), do: {:reserved, :to} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_t(b1) and is_r(b2) and is_a(b3) and is_i(b4) and is_l(b5) and is_i(b6) and is_n(b7) and is_g(b8), do: {:reserved, :trailing} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_l(b6) and is_a(b7) and is_t(b8) and is_e(b9), do: {:reserved, :translate} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_l(b6) and is_a(b7) and is_t(b8) and is_e(b9) and b10 in ~c"_" and is_r(b11) and is_e(b12) and is_g(b13) and is_e(b14) and is_x(b15), do: {:reserved, :translate_regex} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_l(b6) and is_a(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11), do: {:reserved, :translation} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_t(b1) and is_r(b2) and is_e(b3) and is_a(b4) and is_t(b5), do: {:reserved, :treat} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_t(b1) and is_r(b2) and is_i(b3) and is_g(b4) and is_g(b5) and is_e(b6) and is_r(b7), do: {:reserved, :trigger} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_r(b2) and is_i(b3) and is_m(b4), do: {:reserved, :trim} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_t(b1) and is_r(b2) and is_i(b3) and is_m(b4) and b5 in ~c"_" and is_a(b6) and is_r(b7) and is_r(b8) and is_a(b9) and is_y(b10), do: {:reserved, :trim_array} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_r(b2) and is_u(b3) and is_e(b4), do: {:reserved, true} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_t(b1) and is_r(b2) and is_u(b3) and is_n(b4) and is_c(b5) and is_a(b6) and is_t(b7) and is_e(b8), do: {:reserved, :truncate} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_u(b1) and is_e(b2) and is_s(b3) and is_c(b4) and is_a(b5) and is_p(b6) and is_e(b7), do: {:reserved, :uescape} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_n(b2) and is_i(b3) and is_o(b4) and is_n(b5), do: {:reserved, :union} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_u(b1) and is_n(b2) and is_i(b3) and is_q(b4) and is_u(b5) and is_e(b6), do: {:reserved, :unique} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_u(b1) and is_n(b2) and is_k(b3) and is_n(b4) and is_o(b5) and is_w(b6) and is_n(b7), do: {:reserved, :unknown} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_u(b1) and is_n(b2) and is_n(b3) and is_e(b4) and is_s(b5) and is_t(b6), do: {:reserved, :unnest} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_u(b1) and is_p(b2) and is_d(b3) and is_a(b4) and is_t(b5) and is_e(b6), do: {:reserved, :update} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_p(b2) and is_p(b3) and is_e(b4) and is_r(b5), do: {:reserved, :upper} - + def tag([[[[[], b1], b2], b3], b4]) when is_u(b1) and is_s(b2) and is_e(b3) and is_r(b4), do: {:reserved, :user} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_s(b2) and is_i(b3) and is_n(b4) and is_g(b5), do: {:reserved, :using} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_v(b1) and is_a(b2) and is_l(b3) and is_u(b4) and is_e(b5), do: {:reserved, :value} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_v(b1) and is_a(b2) and is_l(b3) and is_u(b4) and is_e(b5) and is_s(b6), do: {:reserved, :values} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_v(b1) and is_a(b2) and is_l(b3) and is_u(b4) and is_e(b5) and b6 in ~c"_" and is_o(b7) and is_f(b8), do: {:reserved, :value_of} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_v(b1) and is_a(b2) and is_r(b3) and b4 in ~c"_" and is_p(b5) and is_o(b6) and is_p(b7), do: {:reserved, :var_pop} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_v(b1) and is_a(b2) and is_r(b3) and b4 in ~c"_" and is_s(b5) and is_a(b6) and is_m(b7) and is_p(b8), do: {:reserved, :var_samp} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_v(b1) and is_a(b2) and is_r(b3) and is_b(b4) and is_i(b5) and is_n(b6) and is_a(b7) and is_r(b8) and is_y(b9), do: {:reserved, :varbinary} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_v(b1) and is_a(b2) and is_r(b3) and is_c(b4) and is_h(b5) and is_a(b6) and is_r(b7), do: {:reserved, :varchar} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_v(b1) and is_a(b2) and is_r(b3) and is_y(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:reserved, :varying} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_v(b1) and is_e(b2) and is_r(b3) and is_s(b4) and is_i(b5) and is_o(b6) and is_n(b7) and is_i(b8) and is_n(b9) and is_g(b10), do: {:reserved, :versioning} - + def tag([[[[[], b1], b2], b3], b4]) when is_w(b1) and is_h(b2) and is_e(b3) and is_n(b4), do: {:reserved, :when} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_w(b1) and is_h(b2) and is_e(b3) and is_n(b4) and is_e(b5) and is_v(b6) and is_e(b7) and is_r(b8), do: {:reserved, :whenever} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_w(b1) and is_h(b2) and is_e(b3) and is_r(b4) and is_e(b5), do: {:reserved, :where} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_w(b1) and is_i(b2) and is_d(b3) and is_t(b4) and is_h(b5) and b6 in ~c"_" and is_b(b7) and is_u(b8) and is_c(b9) and is_k(b10) and is_e(b11) and is_t(b12), do: {:reserved, :width_bucket} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_w(b1) and is_i(b2) and is_n(b3) and is_d(b4) and is_o(b5) and is_w(b6), do: {:reserved, :window} - + def tag([[[[[], b1], b2], b3], b4]) when is_w(b1) and is_i(b2) and is_t(b3) and is_h(b4), do: {:reserved, :with} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_w(b1) and is_i(b2) and is_t(b3) and is_h(b4) and is_i(b5) and is_n(b6), do: {:reserved, :within} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_w(b1) and is_i(b2) and is_t(b3) and is_h(b4) and is_o(b5) and is_u(b6) and is_t(b7), do: {:reserved, :without} - + def tag([[[[[], b1], b2], b3], b4]) when is_y(b1) and is_e(b2) and is_a(b3) and is_r(b4), do: {:reserved, :year} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_i(b2) and is_m(b3) and is_i(b4) and is_t(b5), do: {:reserved, :limit} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_i(b1) and is_l(b2) and is_i(b3) and is_k(b4) and is_e(b5), do: {:reserved, :ilike} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_b(b1) and is_a(b2) and is_c(b3) and is_k(b4) and is_w(b5) and is_a(b6) and is_r(b7) and is_d(b8), do: {:reserved, :backward} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_f(b1) and is_o(b2) and is_r(b3) and is_w(b4) and is_a(b5) and is_r(b6) and is_d(b7), do: {:reserved, :forward} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_i(b1) and is_s(b2) and is_n(b3) and is_u(b4) and is_l(b5) and is_l(b6), do: {:reserved, :isnull} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_n(b1) and is_o(b2) and is_t(b3) and is_n(b4) and is_u(b5) and is_l(b6) and is_l(b7), do: {:reserved, :notnull} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_a(b2) and is_t(b3) and is_e(b4) and is_t(b5) and is_i(b6) and is_m(b7) and is_e(b8), do: {:reserved, :datetime} - + def tag([[[[[], b1], b2], b3], b4]) when is_f(b1) and is_l(b2) and is_a(b3) and is_g(b4), do: {:reserved, :flag} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_k(b1) and is_e(b2) and is_y(b3) and is_v(b4) and is_a(b5) and is_l(b6) and is_u(b7) and is_e(b8), do: {:reserved, :keyvalue} - + def tag([[[[[], b1], b2], b3], b4]) when is_l(b1) and is_a(b2) and is_s(b3) and is_t(b4), do: {:reserved, :last} - + def tag([[[[], b1], b2], b3]) when is_l(b1) and is_a(b2) and is_x(b3), do: {:reserved, :lax} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_n(b1) and is_u(b2) and is_m(b3) and is_b(b4) and is_e(b5) and is_r(b6), do: {:reserved, :number} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_i(b2) and is_z(b3) and is_e(b4), do: {:reserved, :size} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_t(b2) and is_a(b3) and is_r(b4) and is_t(b5) and is_s(b6), do: {:reserved, :starts} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_t(b2) and is_r(b3) and is_i(b4) and is_c(b5) and is_t(b6), do: {:reserved, :strict} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_t(b2) and is_r(b3) and is_i(b4) and is_n(b5) and is_g(b6), do: {:reserved, :string} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_t(b1) and is_i(b2) and is_m(b3) and is_e(b4) and b5 in ~c"_" and is_t(b6) and is_z(b7), do: {:reserved, :time_tz} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_t(b1) and is_i(b2) and is_m(b3) and is_e(b4) and is_s(b5) and is_t(b6) and is_a(b7) and is_m(b8) and is_p(b9) and b10 in ~c"_" and is_t(b11) and is_z(b12), do: {:reserved, :timestamp_tz} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_y(b2) and is_p(b3) and is_e(b4), do: {:reserved, :type} - - + + def tag([[], b1]) when is_a(b1), do: {:non_reserved, :a} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_a(b1) and is_b(b2) and is_s(b3) and is_o(b4) and is_l(b5) and is_u(b6) and is_t(b7) and is_e(b8), do: {:non_reserved, :absolute} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_a(b1) and is_c(b2) and is_t(b3) and is_i(b4) and is_o(b5) and is_n(b6), do: {:non_reserved, :action} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_d(b2) and is_a(b3), do: {:non_reserved, :ada} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_d(b2) and is_d(b3), do: {:non_reserved, :add} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_a(b1) and is_d(b2) and is_m(b3) and is_i(b4) and is_n(b5), do: {:non_reserved, :admin} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_a(b1) and is_f(b2) and is_t(b3) and is_e(b4) and is_r(b5), do: {:non_reserved, :after} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_a(b1) and is_l(b2) and is_w(b3) and is_a(b4) and is_y(b5) and is_s(b6), do: {:non_reserved, :always} - + def tag([[[[], b1], b2], b3]) when is_a(b1) and is_s(b2) and is_c(b3), do: {:non_reserved, :asc} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_a(b1) and is_s(b2) and is_s(b3) and is_e(b4) and is_r(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9), do: {:non_reserved, :assertion} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_a(b1) and is_s(b2) and is_s(b3) and is_i(b4) and is_g(b5) and is_n(b6) and is_m(b7) and is_e(b8) and is_n(b9) and is_t(b10), do: {:non_reserved, :assignment} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_a(b1) and is_t(b2) and is_t(b3) and is_r(b4) and is_i(b5) and is_b(b6) and is_u(b7) and is_t(b8) and is_e(b9), do: {:non_reserved, :attribute} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_a(b1) and is_t(b2) and is_t(b3) and is_r(b4) and is_i(b5) and is_b(b6) and is_u(b7) and is_t(b8) and is_e(b9) and is_s(b10), do: {:non_reserved, :attributes} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_b(b1) and is_e(b2) and is_f(b3) and is_o(b4) and is_r(b5) and is_e(b6), do: {:non_reserved, :before} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_b(b1) and is_e(b2) and is_r(b3) and is_n(b4) and is_o(b5) and is_u(b6) and is_l(b7) and is_l(b8) and is_i(b9), do: {:non_reserved, :bernoulli} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_b(b1) and is_r(b2) and is_e(b3) and is_a(b4) and is_d(b5) and is_t(b6) and is_h(b7), do: {:non_reserved, :breadth} - + def tag([[], b1]) when is_c(b1), do: {:non_reserved, :c} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_a(b2) and is_s(b3) and is_c(b4) and is_a(b5) and is_d(b6) and is_e(b7), do: {:non_reserved, :cascade} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_a(b2) and is_t(b3) and is_a(b4) and is_l(b5) and is_o(b6) and is_g(b7), do: {:non_reserved, :catalog} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_a(b2) and is_t(b3) and is_a(b4) and is_l(b5) and is_o(b6) and is_g(b7) and b8 in ~c"_" and is_n(b9) and is_a(b10) and is_m(b11) and is_e(b12), do: {:non_reserved, :catalog_name} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_h(b2) and is_a(b3) and is_i(b4) and is_n(b5), do: {:non_reserved, :chain} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_c(b1) and is_h(b2) and is_a(b3) and is_i(b4) and is_n(b5) and is_i(b6) and is_n(b7) and is_g(b8), do: {:non_reserved, :chaining} - + def tag([[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_s(b11) and is_e(b12) and is_t(b13) and b14 in ~c"_" and is_c(b15) and is_a(b16) and is_t(b17) and is_a(b18) and is_l(b19) and is_o(b20) and is_g(b21), do: {:non_reserved, :character_set_catalog} - + def tag([[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_s(b11) and is_e(b12) and is_t(b13) and b14 in ~c"_" and is_n(b15) and is_a(b16) and is_m(b17) and is_e(b18), do: {:non_reserved, :character_set_name} - + def tag([[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_s(b11) and is_e(b12) and is_t(b13) and b14 in ~c"_" and is_s(b15) and is_c(b16) and is_h(b17) and is_e(b18) and is_m(b19) and is_a(b20), do: {:non_reserved, :character_set_schema} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9) and is_i(b10) and is_s(b11) and is_t(b12) and is_i(b13) and is_c(b14) and is_s(b15), do: {:non_reserved, :characteristics} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_c(b1) and is_h(b2) and is_a(b3) and is_r(b4) and is_a(b5) and is_c(b6) and is_t(b7) and is_e(b8) and is_r(b9) and is_s(b10), do: {:non_reserved, :characters} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_c(b1) and is_l(b2) and is_a(b3) and is_s(b4) and is_s(b5) and b6 in ~c"_" and is_o(b7) and is_r(b8) and is_i(b9) and is_g(b10) and is_i(b11) and is_n(b12), do: {:non_reserved, :class_origin} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_c(b1) and is_o(b2) and is_b(b3) and is_o(b4) and is_l(b5), do: {:non_reserved, :cobol} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_c(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_a(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9), do: {:non_reserved, :collation} - + def tag([[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17]) when is_c(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_a(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9) and b10 in ~c"_" and is_c(b11) and is_a(b12) and is_t(b13) and is_a(b14) and is_l(b15) and is_o(b16) and is_g(b17), do: {:non_reserved, :collation_catalog} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_c(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_a(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9) and b10 in ~c"_" and is_n(b11) and is_a(b12) and is_m(b13) and is_e(b14), do: {:non_reserved, :collation_name} - + def tag([[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16]) when is_c(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_a(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9) and b10 in ~c"_" and is_s(b11) and is_c(b12) and is_h(b13) and is_e(b14) and is_m(b15) and is_a(b16), do: {:non_reserved, :collation_schema} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_c(b1) and is_o(b2) and is_l(b3) and is_u(b4) and is_m(b5) and is_n(b6) and is_s(b7), do: {:non_reserved, :columns} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_o(b2) and is_l(b3) and is_u(b4) and is_m(b5) and is_n(b6) and b7 in ~c"_" and is_n(b8) and is_a(b9) and is_m(b10) and is_e(b11), do: {:non_reserved, :column_name} - + def tag([[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16]) when is_c(b1) and is_o(b2) and is_m(b3) and is_m(b4) and is_a(b5) and is_n(b6) and is_d(b7) and b8 in ~c"_" and is_f(b9) and is_u(b10) and is_n(b11) and is_c(b12) and is_t(b13) and is_i(b14) and is_o(b15) and is_n(b16), do: {:non_reserved, :command_function} - + def tag([[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21]) when is_c(b1) and is_o(b2) and is_m(b3) and is_m(b4) and is_a(b5) and is_n(b6) and is_d(b7) and b8 in ~c"_" and is_f(b9) and is_u(b10) and is_n(b11) and is_c(b12) and is_t(b13) and is_i(b14) and is_o(b15) and is_n(b16) and b17 in ~c"_" and is_c(b18) and is_o(b19) and is_d(b20) and is_e(b21), do: {:non_reserved, :command_function_code} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_c(b1) and is_o(b2) and is_m(b3) and is_m(b4) and is_i(b5) and is_t(b6) and is_t(b7) and is_e(b8) and is_d(b9), do: {:non_reserved, :committed} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_o(b2) and is_n(b3) and is_d(b4) and is_i(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9) and is_a(b10) and is_l(b11), do: {:non_reserved, :conditional} - + def tag([[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16]) when is_c(b1) and is_o(b2) and is_n(b3) and is_d(b4) and is_i(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9) and b10 in ~c"_" and is_n(b11) and is_u(b12) and is_m(b13) and is_b(b14) and is_e(b15) and is_r(b16), do: {:non_reserved, :condition_number} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_c(b1) and is_o(b2) and is_n(b3) and is_n(b4) and is_e(b5) and is_c(b6) and is_t(b7) and is_i(b8) and is_o(b9) and is_n(b10), do: {:non_reserved, :connection} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_c(b1) and is_o(b2) and is_n(b3) and is_n(b4) and is_e(b5) and is_c(b6) and is_t(b7) and is_i(b8) and is_o(b9) and is_n(b10) and b11 in ~c"_" and is_n(b12) and is_a(b13) and is_m(b14) and is_e(b15), do: {:non_reserved, :connection_name} - + def tag([[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18]) when is_c(b1) and is_o(b2) and is_n(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_a(b7) and is_i(b8) and is_n(b9) and is_t(b10) and b11 in ~c"_" and is_c(b12) and is_a(b13) and is_t(b14) and is_a(b15) and is_l(b16) and is_o(b17) and is_g(b18), do: {:non_reserved, :constraint_catalog} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_c(b1) and is_o(b2) and is_n(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_a(b7) and is_i(b8) and is_n(b9) and is_t(b10) and b11 in ~c"_" and is_n(b12) and is_a(b13) and is_m(b14) and is_e(b15), do: {:non_reserved, :constraint_name} - + def tag([[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17]) when is_c(b1) and is_o(b2) and is_n(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_a(b7) and is_i(b8) and is_n(b9) and is_t(b10) and b11 in ~c"_" and is_s(b12) and is_c(b13) and is_h(b14) and is_e(b15) and is_m(b16) and is_a(b17), do: {:non_reserved, :constraint_schema} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_o(b2) and is_n(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_a(b7) and is_i(b8) and is_n(b9) and is_t(b10) and is_s(b11), do: {:non_reserved, :constraints} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_o(b2) and is_n(b3) and is_s(b4) and is_t(b5) and is_r(b6) and is_u(b7) and is_c(b8) and is_t(b9) and is_o(b10) and is_r(b11), do: {:non_reserved, :constructor} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_c(b1) and is_o(b2) and is_n(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_u(b7) and is_e(b8), do: {:non_reserved, :continue} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_o(b2) and is_p(b3) and is_a(b4) and is_r(b5) and is_t(b6) and is_i(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11), do: {:non_reserved, :copartition} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_c(b1) and is_u(b2) and is_r(b3) and is_s(b4) and is_o(b5) and is_r(b6) and b7 in ~c"_" and is_n(b8) and is_a(b9) and is_m(b10) and is_e(b11), do: {:non_reserved, :cursor_name} - + def tag([[[[[], b1], b2], b3], b4]) when is_d(b1) and is_a(b2) and is_t(b3) and is_a(b4), do: {:non_reserved, :data} - + def tag([[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22]) when is_d(b1) and is_a(b2) and is_t(b3) and is_e(b4) and is_t(b5) and is_i(b6) and is_m(b7) and is_e(b8) and b9 in ~c"_" and is_i(b10) and is_n(b11) and is_t(b12) and is_e(b13) and is_r(b14) and is_v(b15) and is_a(b16) and is_l(b17) and b18 in ~c"_" and is_c(b19) and is_o(b20) and is_d(b21) and is_e(b22), do: {:non_reserved, :datetime_interval_code} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25], b26], b27]) when is_d(b1) and is_a(b2) and is_t(b3) and is_e(b4) and is_t(b5) and is_i(b6) and is_m(b7) and is_e(b8) and b9 in ~c"_" and is_i(b10) and is_n(b11) and is_t(b12) and is_e(b13) and is_r(b14) and is_v(b15) and is_a(b16) and is_l(b17) and b18 in ~c"_" and is_p(b19) and is_r(b20) and is_e(b21) and is_c(b22) and is_i(b23) and is_s(b24) and is_i(b25) and is_o(b26) and is_n(b27), do: {:non_reserved, :datetime_interval_precision} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_e(b2) and is_f(b3) and is_a(b4) and is_u(b5) and is_l(b6) and is_t(b7) and is_s(b8), do: {:non_reserved, :defaults} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_d(b1) and is_e(b2) and is_f(b3) and is_e(b4) and is_r(b5) and is_r(b6) and is_a(b7) and is_b(b8) and is_l(b9) and is_e(b10), do: {:non_reserved, :deferrable} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_e(b2) and is_f(b3) and is_e(b4) and is_r(b5) and is_r(b6) and is_e(b7) and is_d(b8), do: {:non_reserved, :deferred} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_e(b2) and is_f(b3) and is_i(b4) and is_n(b5) and is_e(b6) and is_d(b7), do: {:non_reserved, :defined} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_e(b2) and is_f(b3) and is_i(b4) and is_n(b5) and is_e(b6) and is_r(b7), do: {:non_reserved, :definer} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_d(b1) and is_e(b2) and is_g(b3) and is_r(b4) and is_e(b5) and is_e(b6), do: {:non_reserved, :degree} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_d(b1) and is_e(b2) and is_p(b3) and is_t(b4) and is_h(b5), do: {:non_reserved, :depth} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_d(b1) and is_e(b2) and is_r(b3) and is_i(b4) and is_v(b5) and is_e(b6) and is_d(b7), do: {:non_reserved, :derived} - + def tag([[[[[], b1], b2], b3], b4]) when is_d(b1) and is_e(b2) and is_s(b3) and is_c(b4), do: {:non_reserved, :desc} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_d(b1) and is_e(b2) and is_s(b3) and is_c(b4) and is_r(b5) and is_i(b6) and is_p(b7) and is_t(b8) and is_o(b9) and is_r(b10), do: {:non_reserved, :descriptor} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_d(b1) and is_i(b2) and is_a(b3) and is_g(b4) and is_n(b5) and is_o(b6) and is_s(b7) and is_t(b8) and is_i(b9) and is_c(b10) and is_s(b11), do: {:non_reserved, :diagnostics} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_d(b1) and is_i(b2) and is_s(b3) and is_p(b4) and is_a(b5) and is_t(b6) and is_c(b7) and is_h(b8), do: {:non_reserved, :dispatch} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_d(b1) and is_o(b2) and is_m(b3) and is_a(b4) and is_i(b5) and is_n(b6), do: {:non_reserved, :domain} - + def tag([[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16]) when is_d(b1) and is_y(b2) and is_n(b3) and is_a(b4) and is_m(b5) and is_i(b6) and is_c(b7) and b8 in ~c"_" and is_f(b9) and is_u(b10) and is_n(b11) and is_c(b12) and is_t(b13) and is_i(b14) and is_o(b15) and is_n(b16), do: {:non_reserved, :dynamic_function} - + def tag([[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21]) when is_d(b1) and is_y(b2) and is_n(b3) and is_a(b4) and is_m(b5) and is_i(b6) and is_c(b7) and b8 in ~c"_" and is_f(b9) and is_u(b10) and is_n(b11) and is_c(b12) and is_t(b13) and is_i(b14) and is_o(b15) and is_n(b16) and b17 in ~c"_" and is_c(b18) and is_o(b19) and is_d(b20) and is_e(b21), do: {:non_reserved, :dynamic_function_code} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_e(b1) and is_n(b2) and is_c(b3) and is_o(b4) and is_d(b5) and is_i(b6) and is_n(b7) and is_g(b8), do: {:non_reserved, :encoding} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_e(b1) and is_n(b2) and is_f(b3) and is_o(b4) and is_r(b5) and is_c(b6) and is_e(b7) and is_d(b8), do: {:non_reserved, :enforced} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_e(b1) and is_r(b2) and is_r(b3) and is_o(b4) and is_r(b5), do: {:non_reserved, :error} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_e(b1) and is_x(b2) and is_c(b3) and is_l(b4) and is_u(b5) and is_d(b6) and is_e(b7), do: {:non_reserved, :exclude} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_e(b1) and is_x(b2) and is_c(b3) and is_l(b4) and is_u(b5) and is_d(b6) and is_i(b7) and is_n(b8) and is_g(b9), do: {:non_reserved, :excluding} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_e(b1) and is_x(b2) and is_p(b3) and is_r(b4) and is_e(b5) and is_s(b6) and is_s(b7) and is_i(b8) and is_o(b9) and is_n(b10), do: {:non_reserved, :expression} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_i(b2) and is_n(b3) and is_a(b4) and is_l(b5), do: {:non_reserved, :final} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_f(b1) and is_i(b2) and is_n(b3) and is_i(b4) and is_s(b5) and is_h(b6), do: {:non_reserved, :finish} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_i(b2) and is_r(b3) and is_s(b4) and is_t(b5), do: {:non_reserved, :first} - + def tag([[[[[], b1], b2], b3], b4]) when is_f(b1) and is_l(b2) and is_a(b3) and is_g(b4), do: {:non_reserved, :flag} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_f(b1) and is_o(b2) and is_l(b3) and is_l(b4) and is_o(b5) and is_w(b6) and is_i(b7) and is_n(b8) and is_g(b9), do: {:non_reserved, :following} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_f(b1) and is_o(b2) and is_r(b3) and is_m(b4) and is_a(b5) and is_t(b6), do: {:non_reserved, :format} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_f(b1) and is_o(b2) and is_r(b3) and is_t(b4) and is_r(b5) and is_a(b6) and is_n(b7), do: {:non_reserved, :fortran} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_f(b1) and is_o(b2) and is_u(b3) and is_n(b4) and is_d(b5), do: {:non_reserved, :found} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_f(b1) and is_u(b2) and is_l(b3) and is_f(b4) and is_i(b5) and is_l(b6) and is_l(b7), do: {:non_reserved, :fulfill} - + def tag([[], b1]) when is_g(b1), do: {:non_reserved, :g} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_g(b1) and is_e(b2) and is_n(b3) and is_e(b4) and is_r(b5) and is_a(b6) and is_l(b7), do: {:non_reserved, :general} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_g(b1) and is_e(b2) and is_n(b3) and is_e(b4) and is_r(b5) and is_a(b6) and is_t(b7) and is_e(b8) and is_d(b9), do: {:non_reserved, :generated} - + def tag([[[], b1], b2]) when is_g(b1) and is_o(b2), do: {:non_reserved, :go} - + def tag([[[[[], b1], b2], b3], b4]) when is_g(b1) and is_o(b2) and is_t(b3) and is_o(b4), do: {:non_reserved, :goto} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_g(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_t(b5) and is_e(b6) and is_d(b7), do: {:non_reserved, :granted} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_h(b1) and is_i(b2) and is_e(b3) and is_r(b4) and is_a(b5) and is_r(b6) and is_c(b7) and is_h(b8) and is_y(b9), do: {:non_reserved, :hierarchy} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_i(b1) and is_g(b2) and is_n(b3) and is_o(b4) and is_r(b5) and is_e(b6), do: {:non_reserved, :ignore} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_m(b2) and is_m(b3) and is_e(b4) and is_d(b5) and is_i(b6) and is_a(b7) and is_t(b8) and is_e(b9), do: {:non_reserved, :immediate} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_i(b1) and is_m(b2) and is_m(b3) and is_e(b4) and is_d(b5) and is_i(b6) and is_a(b7) and is_t(b8) and is_e(b9) and is_l(b10) and is_y(b11), do: {:non_reserved, :immediately} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_i(b1) and is_m(b2) and is_p(b3) and is_l(b4) and is_e(b5) and is_m(b6) and is_e(b7) and is_n(b8) and is_t(b9) and is_a(b10) and is_t(b11) and is_i(b12) and is_o(b13) and is_n(b14), do: {:non_reserved, :implementation} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_n(b2) and is_c(b3) and is_l(b4) and is_u(b5) and is_d(b6) and is_i(b7) and is_n(b8) and is_g(b9), do: {:non_reserved, :including} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_n(b2) and is_c(b3) and is_r(b4) and is_e(b5) and is_m(b6) and is_e(b7) and is_n(b8) and is_t(b9), do: {:non_reserved, :increment} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_n(b2) and is_i(b3) and is_t(b4) and is_i(b5) and is_a(b6) and is_l(b7) and is_l(b8) and is_y(b9), do: {:non_reserved, :initially} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_i(b1) and is_n(b2) and is_p(b3) and is_u(b4) and is_t(b5), do: {:non_reserved, :input} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_i(b1) and is_n(b2) and is_s(b3) and is_t(b4) and is_a(b5) and is_n(b6) and is_c(b7) and is_e(b8), do: {:non_reserved, :instance} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_i(b1) and is_n(b2) and is_s(b3) and is_t(b4) and is_a(b5) and is_n(b6) and is_t(b7) and is_i(b8) and is_a(b9) and is_b(b10) and is_l(b11) and is_e(b12), do: {:non_reserved, :instantiable} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_i(b1) and is_n(b2) and is_s(b3) and is_t(b4) and is_e(b5) and is_a(b6) and is_d(b7), do: {:non_reserved, :instead} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_i(b1) and is_n(b2) and is_v(b3) and is_o(b4) and is_k(b5) and is_e(b6) and is_r(b7), do: {:non_reserved, :invoker} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_i(b1) and is_s(b2) and is_o(b3) and is_l(b4) and is_a(b5) and is_t(b6) and is_i(b7) and is_o(b8) and is_n(b9), do: {:non_reserved, :isolation} - + def tag([[], b1]) when is_k(b1), do: {:non_reserved, :k} - + def tag([[[[[], b1], b2], b3], b4]) when is_k(b1) and is_e(b2) and is_e(b3) and is_p(b4), do: {:non_reserved, :keep} - + def tag([[[[], b1], b2], b3]) when is_k(b1) and is_e(b2) and is_y(b3), do: {:non_reserved, :key} - + def tag([[[[[], b1], b2], b3], b4]) when is_k(b1) and is_e(b2) and is_y(b3) and is_s(b4), do: {:non_reserved, :keys} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_k(b1) and is_e(b2) and is_y(b3) and b4 in ~c"_" and is_m(b5) and is_e(b6) and is_m(b7) and is_b(b8) and is_e(b9) and is_r(b10), do: {:non_reserved, :key_member} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_k(b1) and is_e(b2) and is_y(b3) and b4 in ~c"_" and is_t(b5) and is_y(b6) and is_p(b7) and is_e(b8), do: {:non_reserved, :key_type} - + def tag([[[[[], b1], b2], b3], b4]) when is_l(b1) and is_a(b2) and is_s(b3) and is_t(b4), do: {:non_reserved, :last} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_l(b1) and is_e(b2) and is_n(b3) and is_g(b4) and is_t(b5) and is_h(b6), do: {:non_reserved, :length} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_l(b1) and is_e(b2) and is_v(b3) and is_e(b4) and is_l(b5), do: {:non_reserved, :level} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_l(b1) and is_o(b2) and is_c(b3) and is_a(b4) and is_t(b5) and is_o(b6) and is_r(b7), do: {:non_reserved, :locator} - + def tag([[], b1]) when is_m(b1), do: {:non_reserved, :m} - + def tag([[[[], b1], b2], b3]) when is_m(b1) and is_a(b2) and is_p(b3), do: {:non_reserved, :map} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_m(b1) and is_a(b2) and is_t(b3) and is_c(b4) and is_h(b5) and is_e(b6) and is_d(b7), do: {:non_reserved, :matched} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_m(b1) and is_a(b2) and is_x(b3) and is_v(b4) and is_a(b5) and is_l(b6) and is_u(b7) and is_e(b8), do: {:non_reserved, :maxvalue} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_m(b1) and is_e(b2) and is_a(b3) and is_s(b4) and is_u(b5) and is_r(b6) and is_e(b7) and is_s(b8), do: {:non_reserved, :measures} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_m(b1) and is_e(b2) and is_s(b3) and is_s(b4) and is_a(b5) and is_g(b6) and is_e(b7) and b8 in ~c"_" and is_l(b9) and is_e(b10) and is_n(b11) and is_g(b12) and is_t(b13) and is_h(b14), do: {:non_reserved, :message_length} - + def tag([[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20]) when is_m(b1) and is_e(b2) and is_s(b3) and is_s(b4) and is_a(b5) and is_g(b6) and is_e(b7) and b8 in ~c"_" and is_o(b9) and is_c(b10) and is_t(b11) and is_e(b12) and is_t(b13) and b14 in ~c"_" and is_l(b15) and is_e(b16) and is_n(b17) and is_g(b18) and is_t(b19) and is_h(b20), do: {:non_reserved, :message_octet_length} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_m(b1) and is_e(b2) and is_s(b3) and is_s(b4) and is_a(b5) and is_g(b6) and is_e(b7) and b8 in ~c"_" and is_t(b9) and is_e(b10) and is_x(b11) and is_t(b12), do: {:non_reserved, :message_text} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_m(b1) and is_i(b2) and is_n(b3) and is_v(b4) and is_a(b5) and is_l(b6) and is_u(b7) and is_e(b8), do: {:non_reserved, :minvalue} - + def tag([[[[[], b1], b2], b3], b4]) when is_m(b1) and is_o(b2) and is_r(b3) and is_e(b4), do: {:non_reserved, :more} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_m(b1) and is_u(b2) and is_m(b3) and is_p(b4) and is_s(b5), do: {:non_reserved, :mumps} - + def tag([[[[[], b1], b2], b3], b4]) when is_n(b1) and is_a(b2) and is_m(b3) and is_e(b4), do: {:non_reserved, :name} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_n(b1) and is_a(b2) and is_m(b3) and is_e(b4) and is_s(b5), do: {:non_reserved, :names} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_n(b1) and is_e(b2) and is_s(b3) and is_t(b4) and is_e(b5) and is_d(b6), do: {:non_reserved, :nested} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_n(b1) and is_e(b2) and is_s(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:non_reserved, :nesting} - + def tag([[[[[], b1], b2], b3], b4]) when is_n(b1) and is_e(b2) and is_x(b3) and is_t(b4), do: {:non_reserved, :next} - + def tag([[[[], b1], b2], b3]) when is_n(b1) and is_f(b2) and is_c(b3), do: {:non_reserved, :nfc} - + def tag([[[[], b1], b2], b3]) when is_n(b1) and is_f(b2) and is_d(b3), do: {:non_reserved, :nfd} - + def tag([[[[[], b1], b2], b3], b4]) when is_n(b1) and is_f(b2) and is_k(b3) and is_c(b4), do: {:non_reserved, :nfkc} - + def tag([[[[[], b1], b2], b3], b4]) when is_n(b1) and is_f(b2) and is_k(b3) and is_d(b4), do: {:non_reserved, :nfkd} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_n(b1) and is_o(b2) and is_r(b3) and is_m(b4) and is_a(b5) and is_l(b6) and is_i(b7) and is_z(b8) and is_e(b9) and is_d(b10), do: {:non_reserved, :normalized} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_n(b1) and is_u(b2) and is_l(b3) and is_l(b4) and b5 in ~c"_" and is_o(b6) and is_r(b7) and is_d(b8) and is_e(b9) and is_r(b10) and is_i(b11) and is_n(b12) and is_g(b13), do: {:non_reserved, :null_ordering} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_n(b1) and is_u(b2) and is_l(b3) and is_l(b4) and is_a(b5) and is_b(b6) and is_l(b7) and is_e(b8), do: {:non_reserved, :nullable} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_n(b1) and is_u(b2) and is_l(b3) and is_l(b4) and is_s(b5), do: {:non_reserved, :nulls} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_n(b1) and is_u(b2) and is_m(b3) and is_b(b4) and is_e(b5) and is_r(b6), do: {:non_reserved, :number} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_o(b1) and is_b(b2) and is_j(b3) and is_e(b4) and is_c(b5) and is_t(b6), do: {:non_reserved, :object} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_o(b1) and is_c(b2) and is_c(b3) and is_u(b4) and is_r(b5) and is_r(b6) and is_e(b7) and is_n(b8) and is_c(b9) and is_e(b10), do: {:non_reserved, :occurrence} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_o(b1) and is_c(b2) and is_t(b3) and is_e(b4) and is_t(b5) and is_s(b6), do: {:non_reserved, :octets} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_o(b1) and is_p(b2) and is_t(b3) and is_i(b4) and is_o(b5) and is_n(b6), do: {:non_reserved, :option} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_o(b1) and is_p(b2) and is_t(b3) and is_i(b4) and is_o(b5) and is_n(b6) and is_s(b7), do: {:non_reserved, :options} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_o(b1) and is_r(b2) and is_d(b3) and is_e(b4) and is_r(b5) and is_i(b6) and is_n(b7) and is_g(b8), do: {:non_reserved, :ordering} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_o(b1) and is_r(b2) and is_d(b3) and is_i(b4) and is_n(b5) and is_a(b6) and is_l(b7) and is_i(b8) and is_t(b9) and is_y(b10), do: {:non_reserved, :ordinality} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_o(b1) and is_t(b2) and is_h(b3) and is_e(b4) and is_r(b5) and is_s(b6), do: {:non_reserved, :others} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_o(b1) and is_u(b2) and is_t(b3) and is_p(b4) and is_u(b5) and is_t(b6), do: {:non_reserved, :output} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_o(b1) and is_v(b2) and is_e(b3) and is_r(b4) and is_f(b5) and is_l(b6) and is_o(b7) and is_w(b8), do: {:non_reserved, :overflow} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_o(b1) and is_v(b2) and is_e(b3) and is_r(b4) and is_r(b5) and is_i(b6) and is_d(b7) and is_i(b8) and is_n(b9) and is_g(b10), do: {:non_reserved, :overriding} - + def tag([[], b1]) when is_p(b1), do: {:non_reserved, :p} - + def tag([[[[], b1], b2], b3]) when is_p(b1) and is_a(b2) and is_d(b3), do: {:non_reserved, :pad} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_m(b11) and is_o(b12) and is_d(b13) and is_e(b14), do: {:non_reserved, :parameter_mode} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_n(b11) and is_a(b12) and is_m(b13) and is_e(b14), do: {:non_reserved, :parameter_name} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25], b26]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_o(b11) and is_r(b12) and is_d(b13) and is_i(b14) and is_n(b15) and is_a(b16) and is_l(b17) and b18 in ~c"_" and is_p(b19) and is_o(b20) and is_s(b21) and is_i(b22) and is_t(b23) and is_i(b24) and is_o(b25) and is_n(b26), do: {:non_reserved, :parameter_ordinal_position} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25], b26]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_s(b11) and is_p(b12) and is_e(b13) and is_c(b14) and is_i(b15) and is_f(b16) and is_i(b17) and is_c(b18) and b19 in ~c"_" and is_c(b20) and is_a(b21) and is_t(b22) and is_a(b23) and is_l(b24) and is_o(b25) and is_g(b26), do: {:non_reserved, :parameter_specific_catalog} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_s(b11) and is_p(b12) and is_e(b13) and is_c(b14) and is_i(b15) and is_f(b16) and is_i(b17) and is_c(b18) and b19 in ~c"_" and is_n(b20) and is_a(b21) and is_m(b22) and is_e(b23), do: {:non_reserved, :parameter_specific_name} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25]) when is_p(b1) and is_a(b2) and is_r(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_t(b7) and is_e(b8) and is_r(b9) and b10 in ~c"_" and is_s(b11) and is_p(b12) and is_e(b13) and is_c(b14) and is_i(b15) and is_f(b16) and is_i(b17) and is_c(b18) and b19 in ~c"_" and is_s(b20) and is_c(b21) and is_h(b22) and is_e(b23) and is_m(b24) and is_a(b25), do: {:non_reserved, :parameter_specific_schema} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_a(b2) and is_r(b3) and is_t(b4) and is_i(b5) and is_a(b6) and is_l(b7), do: {:non_reserved, :partial} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_p(b1) and is_a(b2) and is_s(b3) and is_c(b4) and is_a(b5) and is_l(b6), do: {:non_reserved, :pascal} - + def tag([[[[[], b1], b2], b3], b4]) when is_p(b1) and is_a(b2) and is_s(b3) and is_s(b4), do: {:non_reserved, :pass} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_a(b2) and is_s(b3) and is_s(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:non_reserved, :passing} - + def tag([[[[[], b1], b2], b3], b4]) when is_p(b1) and is_a(b2) and is_s(b3) and is_t(b4), do: {:non_reserved, :past} - + def tag([[[[[], b1], b2], b3], b4]) when is_p(b1) and is_a(b2) and is_t(b3) and is_h(b4), do: {:non_reserved, :path} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_e(b2) and is_r(b3) and is_m(b4) and is_u(b5) and is_t(b6) and is_e(b7), do: {:non_reserved, :permute} - + def tag([[[[[], b1], b2], b3], b4]) when is_p(b1) and is_i(b2) and is_p(b3) and is_e(b4), do: {:non_reserved, :pipe} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_l(b2) and is_a(b3) and is_c(b4) and is_i(b5) and is_n(b6) and is_g(b7), do: {:non_reserved, :placing} - + def tag([[[[[], b1], b2], b3], b4]) when is_p(b1) and is_l(b2) and is_a(b3) and is_n(b4), do: {:non_reserved, :plan} - + def tag([[[[], b1], b2], b3]) when is_p(b1) and is_l(b2) and is_i(b3), do: {:non_reserved, :pli} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_p(b1) and is_r(b2) and is_e(b3) and is_c(b4) and is_e(b5) and is_d(b6) and is_i(b7) and is_n(b8) and is_g(b9), do: {:non_reserved, :preceding} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_p(b1) and is_r(b2) and is_e(b3) and is_s(b4) and is_e(b5) and is_r(b6) and is_v(b7) and is_e(b8), do: {:non_reserved, :preserve} - + def tag([[[[[], b1], b2], b3], b4]) when is_p(b1) and is_r(b2) and is_e(b3) and is_v(b4), do: {:non_reserved, :prev} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_p(b1) and is_r(b2) and is_i(b3) and is_o(b4) and is_r(b5), do: {:non_reserved, :prior} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_p(b1) and is_r(b2) and is_i(b3) and is_v(b4) and is_a(b5) and is_t(b6) and is_e(b7), do: {:non_reserved, :private} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_p(b1) and is_r(b2) and is_i(b3) and is_v(b4) and is_i(b5) and is_l(b6) and is_e(b7) and is_g(b8) and is_e(b9) and is_s(b10), do: {:non_reserved, :privileges} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_p(b1) and is_r(b2) and is_u(b3) and is_n(b4) and is_e(b5), do: {:non_reserved, :prune} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_p(b1) and is_u(b2) and is_b(b3) and is_l(b4) and is_i(b5) and is_c(b6), do: {:non_reserved, :public} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_q(b1) and is_u(b2) and is_o(b3) and is_t(b4) and is_e(b5) and is_s(b6), do: {:non_reserved, :quotes} - + def tag([[[[[], b1], b2], b3], b4]) when is_r(b1) and is_e(b2) and is_a(b3) and is_d(b4), do: {:non_reserved, :read} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_r(b1) and is_e(b2) and is_l(b3) and is_a(b4) and is_t(b5) and is_i(b6) and is_v(b7) and is_e(b8), do: {:non_reserved, :relative} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_r(b1) and is_e(b2) and is_p(b3) and is_e(b4) and is_a(b5) and is_t(b6) and is_a(b7) and is_b(b8) and is_l(b9) and is_e(b10), do: {:non_reserved, :repeatable} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_e(b2) and is_s(b3) and is_p(b4) and is_e(b5) and is_c(b6) and is_t(b7), do: {:non_reserved, :respect} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_e(b2) and is_s(b3) and is_t(b4) and is_a(b5) and is_r(b6) and is_t(b7), do: {:non_reserved, :restart} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_r(b1) and is_e(b2) and is_s(b3) and is_t(b4) and is_r(b5) and is_i(b6) and is_c(b7) and is_t(b8), do: {:non_reserved, :restrict} - + def tag([[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6) and is_e(b7) and is_d(b8) and b9 in ~c"_" and is_c(b10) and is_a(b11) and is_r(b12) and is_d(b13) and is_i(b14) and is_n(b15) and is_a(b16) and is_l(b17) and is_i(b18) and is_t(b19) and is_y(b20), do: {:non_reserved, :returned_cardinality} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6) and is_e(b7) and is_d(b8) and b9 in ~c"_" and is_l(b10) and is_e(b11) and is_n(b12) and is_g(b13) and is_t(b14) and is_h(b15), do: {:non_reserved, :returned_length} - + def tag([[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6) and is_e(b7) and is_d(b8) and b9 in ~c"_" and is_o(b10) and is_c(b11) and is_t(b12) and is_e(b13) and is_t(b14) and b15 in ~c"_" and is_l(b16) and is_e(b17) and is_n(b18) and is_g(b19) and is_t(b20) and is_h(b21), do: {:non_reserved, :returned_octet_length} - + def tag([[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6) and is_e(b7) and is_d(b8) and b9 in ~c"_" and is_s(b10) and is_q(b11) and is_l(b12) and is_s(b13) and is_t(b14) and is_a(b15) and is_t(b16) and is_e(b17), do: {:non_reserved, :returned_sqlstate} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_r(b1) and is_e(b2) and is_t(b3) and is_u(b4) and is_r(b5) and is_n(b6) and is_i(b7) and is_n(b8) and is_g(b9), do: {:non_reserved, :returning} - + def tag([[[[[], b1], b2], b3], b4]) when is_r(b1) and is_o(b2) and is_l(b3) and is_e(b4), do: {:non_reserved, :role} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_r(b1) and is_o(b2) and is_u(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_e(b7), do: {:non_reserved, :routine} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_r(b1) and is_o(b2) and is_u(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_e(b7) and b8 in ~c"_" and is_c(b9) and is_a(b10) and is_t(b11) and is_a(b12) and is_l(b13) and is_o(b14) and is_g(b15), do: {:non_reserved, :routine_catalog} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_r(b1) and is_o(b2) and is_u(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_e(b7) and b8 in ~c"_" and is_n(b9) and is_a(b10) and is_m(b11) and is_e(b12), do: {:non_reserved, :routine_name} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_r(b1) and is_o(b2) and is_u(b3) and is_t(b4) and is_i(b5) and is_n(b6) and is_e(b7) and b8 in ~c"_" and is_s(b9) and is_c(b10) and is_h(b11) and is_e(b12) and is_m(b13) and is_a(b14), do: {:non_reserved, :routine_schema} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_r(b1) and is_o(b2) and is_w(b3) and b4 in ~c"_" and is_c(b5) and is_o(b6) and is_u(b7) and is_n(b8) and is_t(b9), do: {:non_reserved, :row_count} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_c(b2) and is_a(b3) and is_l(b4) and is_a(b5) and is_r(b6), do: {:non_reserved, :scalar} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_s(b1) and is_c(b2) and is_a(b3) and is_l(b4) and is_e(b5), do: {:non_reserved, :scale} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_c(b2) and is_h(b3) and is_e(b4) and is_m(b5) and is_a(b6), do: {:non_reserved, :schema} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_s(b1) and is_c(b2) and is_h(b3) and is_e(b4) and is_m(b5) and is_a(b6) and b7 in ~c"_" and is_n(b8) and is_a(b9) and is_m(b10) and is_e(b11), do: {:non_reserved, :schema_name} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_s(b1) and is_c(b2) and is_o(b3) and is_p(b4) and is_e(b5) and b6 in ~c"_" and is_c(b7) and is_a(b8) and is_t(b9) and is_a(b10) and is_l(b11) and is_o(b12) and is_g(b13), do: {:non_reserved, :scope_catalog} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_s(b1) and is_c(b2) and is_o(b3) and is_p(b4) and is_e(b5) and b6 in ~c"_" and is_n(b7) and is_a(b8) and is_m(b9) and is_e(b10), do: {:non_reserved, :scope_name} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_s(b1) and is_c(b2) and is_o(b3) and is_p(b4) and is_e(b5) and b6 in ~c"_" and is_s(b7) and is_c(b8) and is_h(b9) and is_e(b10) and is_m(b11) and is_a(b12), do: {:non_reserved, :scope_schema} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_s(b1) and is_e(b2) and is_c(b3) and is_t(b4) and is_i(b5) and is_o(b6) and is_n(b7), do: {:non_reserved, :section} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_s(b1) and is_e(b2) and is_c(b3) and is_u(b4) and is_r(b5) and is_i(b6) and is_t(b7) and is_y(b8), do: {:non_reserved, :security} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_e(b2) and is_l(b3) and is_f(b4), do: {:non_reserved, :self} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_e(b2) and is_m(b3) and is_a(b4) and is_n(b5) and is_t(b6) and is_i(b7) and is_c(b8) and is_s(b9), do: {:non_reserved, :semantics} - + def tag([[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8]) when is_s(b1) and is_e(b2) and is_q(b3) and is_u(b4) and is_e(b5) and is_n(b6) and is_c(b7) and is_e(b8), do: {:non_reserved, :sequence} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_s(b1) and is_e(b2) and is_r(b3) and is_i(b4) and is_a(b5) and is_l(b6) and is_i(b7) and is_z(b8) and is_a(b9) and is_b(b10) and is_l(b11) and is_e(b12), do: {:non_reserved, :serializable} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_s(b1) and is_e(b2) and is_r(b3) and is_v(b4) and is_e(b5) and is_r(b6) and b7 in ~c"_" and is_n(b8) and is_a(b9) and is_m(b10) and is_e(b11), do: {:non_reserved, :server_name} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_s(b1) and is_e(b2) and is_s(b3) and is_s(b4) and is_i(b5) and is_o(b6) and is_n(b7), do: {:non_reserved, :session} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_e(b2) and is_t(b3) and is_s(b4), do: {:non_reserved, :sets} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_i(b2) and is_m(b3) and is_p(b4) and is_l(b5) and is_e(b6), do: {:non_reserved, :simple} - + def tag([[[[[], b1], b2], b3], b4]) when is_s(b1) and is_i(b2) and is_z(b3) and is_e(b4), do: {:non_reserved, :size} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_s(b1) and is_o(b2) and is_r(b3) and is_t(b4) and b5 in ~c"_" and is_d(b6) and is_i(b7) and is_r(b8) and is_e(b9) and is_c(b10) and is_t(b11) and is_i(b12) and is_o(b13) and is_n(b14), do: {:non_reserved, :sort_direction} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_o(b2) and is_u(b3) and is_r(b4) and is_c(b5) and is_e(b6), do: {:non_reserved, :source} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_s(b1) and is_p(b2) and is_a(b3) and is_c(b4) and is_e(b5), do: {:non_reserved, :space} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_s(b1) and is_p(b2) and is_e(b3) and is_c(b4) and is_i(b5) and is_f(b6) and is_i(b7) and is_c(b8) and b9 in ~c"_" and is_n(b10) and is_a(b11) and is_m(b12) and is_e(b13), do: {:non_reserved, :specific_name} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_s(b1) and is_t(b2) and is_a(b3) and is_t(b4) and is_e(b5), do: {:non_reserved, :state} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_t(b2) and is_a(b3) and is_t(b4) and is_e(b5) and is_m(b6) and is_e(b7) and is_n(b8) and is_t(b9), do: {:non_reserved, :statement} - + def tag([[[[[[[], b1], b2], b3], b4], b5], b6]) when is_s(b1) and is_t(b2) and is_r(b3) and is_i(b4) and is_n(b5) and is_g(b6), do: {:non_reserved, :string} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_s(b1) and is_t(b2) and is_r(b3) and is_u(b4) and is_c(b5) and is_t(b6) and is_u(b7) and is_r(b8) and is_e(b9), do: {:non_reserved, :structure} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_s(b1) and is_t(b2) and is_y(b3) and is_l(b4) and is_e(b5), do: {:non_reserved, :style} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_s(b1) and is_u(b2) and is_b(b3) and is_c(b4) and is_l(b5) and is_a(b6) and is_s(b7) and is_s(b8) and b9 in ~c"_" and is_o(b10) and is_r(b11) and is_i(b12) and is_g(b13) and is_i(b14) and is_n(b15), do: {:non_reserved, :subclass_origin} - + def tag([[], b1]) when is_t(b1), do: {:non_reserved, :t} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_t(b1) and is_a(b2) and is_b(b3) and is_l(b4) and is_e(b5) and b6 in ~c"_" and is_n(b7) and is_a(b8) and is_m(b9) and is_e(b10), do: {:non_reserved, :table_name} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_t(b1) and is_e(b2) and is_m(b3) and is_p(b4) and is_o(b5) and is_r(b6) and is_a(b7) and is_r(b8) and is_y(b9), do: {:non_reserved, :temporary} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_t(b1) and is_h(b2) and is_r(b3) and is_o(b4) and is_u(b5) and is_g(b6) and is_h(b7), do: {:non_reserved, :through} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_i(b2) and is_e(b3) and is_s(b4), do: {:non_reserved, :ties} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_t(b1) and is_o(b2) and is_p(b3) and b4 in ~c"_" and is_l(b5) and is_e(b6) and is_v(b7) and is_e(b8) and is_l(b9) and b10 in ~c"_" and is_c(b11) and is_o(b12) and is_u(b13) and is_n(b14) and is_t(b15), do: {:non_reserved, :top_level_count} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_a(b6) and is_c(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11), do: {:non_reserved, :transaction} - + def tag([[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_a(b6) and is_c(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11) and b12 in ~c"_" and is_a(b13) and is_c(b14) and is_t(b15) and is_i(b16) and is_v(b17) and is_e(b18), do: {:non_reserved, :transaction_active} - + def tag([[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_a(b6) and is_c(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11) and is_s(b12) and b13 in ~c"_" and is_c(b14) and is_o(b15) and is_m(b16) and is_m(b17) and is_i(b18) and is_t(b19) and is_t(b20) and is_e(b21) and is_d(b22), do: {:non_reserved, :transactions_committed} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_a(b6) and is_c(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11) and is_s(b12) and b13 in ~c"_" and is_r(b14) and is_o(b15) and is_l(b16) and is_l(b17) and is_e(b18) and is_d(b19) and b20 in ~c"_" and is_b(b21) and is_a(b22) and is_c(b23) and is_k(b24), do: {:non_reserved, :transactions_rolled_back} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_f(b6) and is_o(b7) and is_r(b8) and is_m(b9), do: {:non_reserved, :transform} - + def tag([[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10]) when is_t(b1) and is_r(b2) and is_a(b3) and is_n(b4) and is_s(b5) and is_f(b6) and is_o(b7) and is_r(b8) and is_m(b9) and is_s(b10), do: {:non_reserved, :transforms} - + def tag([[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15]) when is_t(b1) and is_r(b2) and is_i(b3) and is_g(b4) and is_g(b5) and is_e(b6) and is_r(b7) and b8 in ~c"_" and is_c(b9) and is_a(b10) and is_t(b11) and is_a(b12) and is_l(b13) and is_o(b14) and is_g(b15), do: {:non_reserved, :trigger_catalog} - + def tag([[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12]) when is_t(b1) and is_r(b2) and is_i(b3) and is_g(b4) and is_g(b5) and is_e(b6) and is_r(b7) and b8 in ~c"_" and is_n(b9) and is_a(b10) and is_m(b11) and is_e(b12), do: {:non_reserved, :trigger_name} - + def tag([[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14]) when is_t(b1) and is_r(b2) and is_i(b3) and is_g(b4) and is_g(b5) and is_e(b6) and is_r(b7) and b8 in ~c"_" and is_s(b9) and is_c(b10) and is_h(b11) and is_e(b12) and is_m(b13) and is_a(b14), do: {:non_reserved, :trigger_schema} - + def tag([[[[[], b1], b2], b3], b4]) when is_t(b1) and is_y(b2) and is_p(b3) and is_e(b4), do: {:non_reserved, :type} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_u(b1) and is_n(b2) and is_b(b3) and is_o(b4) and is_u(b5) and is_n(b6) and is_d(b7) and is_e(b8) and is_d(b9), do: {:non_reserved, :unbounded} - + def tag([[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11]) when is_u(b1) and is_n(b2) and is_c(b3) and is_o(b4) and is_m(b5) and is_m(b6) and is_i(b7) and is_t(b8) and is_t(b9) and is_e(b10) and is_d(b11), do: {:non_reserved, :uncommitted} - + def tag([[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13]) when is_u(b1) and is_n(b2) and is_c(b3) and is_o(b4) and is_n(b5) and is_d(b6) and is_i(b7) and is_t(b8) and is_i(b9) and is_o(b10) and is_n(b11) and is_a(b12) and is_l(b13), do: {:non_reserved, :unconditional} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_n(b2) and is_d(b3) and is_e(b4) and is_r(b5), do: {:non_reserved, :under} - + def tag([[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9]) when is_u(b1) and is_n(b2) and is_m(b3) and is_a(b4) and is_t(b5) and is_c(b6) and is_h(b7) and is_e(b8) and is_d(b9), do: {:non_reserved, :unmatched} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_u(b1) and is_n(b2) and is_n(b3) and is_a(b4) and is_m(b5) and is_e(b6) and is_d(b7), do: {:non_reserved, :unnamed} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_s(b2) and is_a(b3) and is_g(b4) and is_e(b5), do: {:non_reserved, :usage} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24], b25]) when is_u(b1) and is_s(b2) and is_e(b3) and is_r(b4) and b5 in ~c"_" and is_d(b6) and is_e(b7) and is_f(b8) and is_i(b9) and is_n(b10) and is_e(b11) and is_d(b12) and b13 in ~c"_" and is_t(b14) and is_y(b15) and is_p(b16) and is_e(b17) and b18 in ~c"_" and is_c(b19) and is_a(b20) and is_t(b21) and is_a(b22) and is_l(b23) and is_o(b24) and is_g(b25), do: {:non_reserved, :user_defined_type_catalog} - + def tag([[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22]) when is_u(b1) and is_s(b2) and is_e(b3) and is_r(b4) and b5 in ~c"_" and is_d(b6) and is_e(b7) and is_f(b8) and is_i(b9) and is_n(b10) and is_e(b11) and is_d(b12) and b13 in ~c"_" and is_t(b14) and is_y(b15) and is_p(b16) and is_e(b17) and b18 in ~c"_" and is_c(b19) and is_o(b20) and is_d(b21) and is_e(b22), do: {:non_reserved, :user_defined_type_code} - + def tag([[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22]) when is_u(b1) and is_s(b2) and is_e(b3) and is_r(b4) and b5 in ~c"_" and is_d(b6) and is_e(b7) and is_f(b8) and is_i(b9) and is_n(b10) and is_e(b11) and is_d(b12) and b13 in ~c"_" and is_t(b14) and is_y(b15) and is_p(b16) and is_e(b17) and b18 in ~c"_" and is_n(b19) and is_a(b20) and is_m(b21) and is_e(b22), do: {:non_reserved, :user_defined_type_name} - + def tag([[[[[[[[[[[[[[[[[[[[[[[[[], b1], b2], b3], b4], b5], b6], b7], b8], b9], b10], b11], b12], b13], b14], b15], b16], b17], b18], b19], b20], b21], b22], b23], b24]) when is_u(b1) and is_s(b2) and is_e(b3) and is_r(b4) and b5 in ~c"_" and is_d(b6) and is_e(b7) and is_f(b8) and is_i(b9) and is_n(b10) and is_e(b11) and is_d(b12) and b13 in ~c"_" and is_t(b14) and is_y(b15) and is_p(b16) and is_e(b17) and b18 in ~c"_" and is_s(b19) and is_c(b20) and is_h(b21) and is_e(b22) and is_m(b23) and is_a(b24), do: {:non_reserved, :user_defined_type_schema} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_t(b2) and is_f(b3) and b4 in ~c"1" and b5 in ~c"6", do: {:non_reserved, :utf16} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_u(b1) and is_t(b2) and is_f(b3) and b4 in ~c"3" and b5 in ~c"2", do: {:non_reserved, :utf32} - + def tag([[[[[], b1], b2], b3], b4]) when is_u(b1) and is_t(b2) and is_f(b3) and b4 in ~c"8", do: {:non_reserved, :utf8} - + def tag([[[[[], b1], b2], b3], b4]) when is_v(b1) and is_i(b2) and is_e(b3) and is_w(b4), do: {:non_reserved, :view} - + def tag([[[[[], b1], b2], b3], b4]) when is_w(b1) and is_o(b2) and is_r(b3) and is_k(b4), do: {:non_reserved, :work} - + def tag([[[[[[[[], b1], b2], b3], b4], b5], b6], b7]) when is_w(b1) and is_r(b2) and is_a(b3) and is_p(b4) and is_p(b5) and is_e(b6) and is_r(b7), do: {:non_reserved, :wrapper} - + def tag([[[[[[], b1], b2], b3], b4], b5]) when is_w(b1) and is_r(b2) and is_i(b3) and is_t(b4) and is_e(b5), do: {:non_reserved, :write} - + def tag([[[[[], b1], b2], b3], b4]) when is_z(b1) and is_o(b2) and is_n(b3) and is_e(b4), do: {:non_reserved, :zone} - - + + def tag([[[[], ?^], ?-], ?=]), do: :"^-=" - + def tag([[[[], ?<], ?=], ?>]), do: :"<=>" - + def tag([[[[], ?-], ?>], ?>]), do: :"->>" - + def tag([[[[], ?|], ?|], ?/]), do: :"||/" - + def tag([[[[], ?!], ?~], ?*]), do: :"!~*" - + def tag([[[[], ?<], ?<], ?|]), do: :"<<|" - + def tag([[[[], ?|], ?>], ?>]), do: :"|>>" - + def tag([[[[], ?&], ?<], ?|]), do: :"&<|" - + def tag([[[[], ?|], ?&], ?>]), do: :"|&>" - + def tag([[[[], ??], ?-], ?|]), do: :"?-|" - + def tag([[[[], ??], ?|], ?|]), do: :"?||" - + def tag([[[[], ?<], ?<], ?=]), do: :"<<=" - + def tag([[[[], ?>], ?>], ?=]), do: :">>=" - + def tag([[[[], ?#], ?>], ?>]), do: :"#>>" - + def tag([[[[], ?-], ?|], ?-]), do: :"-|-" - + def tag([[[], ?&], ?&]), do: :&& - + def tag([[[], ?|], ?|]), do: :|| - + def tag([[[], ?&], ?=]), do: :"&=" - + def tag([[[], ?^], ?=]), do: :"^=" - + def tag([[[], ?|], ?=]), do: :"|=" - + def tag([[[[], ?|], ?*], ?=]), do: :"|*=" - + def tag([[[], ?>], ?>]), do: :">>" - + def tag([[[], ?<], ?<]), do: :"<<" - + def tag([[[], ?-], ?>]), do: :-> - + def tag([[[], ?:], ?=]), do: :":=" - + def tag([[[], ?+], ?=]), do: :"+=" - + def tag([[[], ?-], ?=]), do: :"-=" - + def tag([[[], ?*], ?=]), do: :"*=" - + def tag([[[], ?/], ?=]), do: :"/=" - + def tag([[[], ?%], ?=]), do: :"%=" - + def tag([[[], ?!], ?>]), do: :"!>" - + def tag([[[], ?!], ?<]), do: :"!<" - + def tag([[[], ?@], ?>]), do: :"@>" - + def tag([[[], ?<], ?@]), do: :"<@" - + def tag([[[], ?|], ?/]), do: :"|/" - + def tag([[[], ?^], ?@]), do: :"^@" - + def tag([[[], ?~], ?*]), do: :"~*" - + def tag([[[], ?!], ?~]), do: :"!~" - + def tag([[[], ?#], ?#]), do: :"##" - + def tag([[[], ?&], ?<]), do: :"&<" - + def tag([[[], ?&], ?>]), do: :"&>" - + def tag([[[], ?<], ?^]), do: :"<^" - + def tag([[[], ?>], ?^]), do: :">^" - + def tag([[[], ??], ?#]), do: :"?#" - + def tag([[[], ??], ?-]), do: :"?-" - + def tag([[[], ??], ?|]), do: :"?|" - + def tag([[[], ?~], ?=]), do: :"~=" - + def tag([[[], ?@], ?@]), do: :"@@" - + def tag([[[], ?!], ?!]), do: :"!!" - + def tag([[[], ?#], ?>]), do: :"#>" - + def tag([[[], ??], ?&]), do: :"?&" - + def tag([[[], ?#], ?-]), do: :"#-" - + def tag([[[], ?@], ??]), do: :"@?" - + def tag([[[], ?:], ?:]), do: :"::" - + + def tag([[[], ?a], ?s]), do: :as + def tag([[[], ?<], ?>]), do: :<> - + def tag([[[], ?>], ?=]), do: :>= - + def tag([[[], ?<], ?=]), do: :<= - + def tag([[[], ?!], ?=]), do: :!= - + def tag([[], ?+]), do: :+ - + def tag([[], ?-]), do: :- - + def tag([[], ?!]), do: :! - + def tag([[], ?&]), do: :& - + def tag([[], ?^]), do: :^ - + def tag([[], ?|]), do: :| - + def tag([[], ?~]), do: :"~" - + def tag([[], ?%]), do: :% - + def tag([[], ?@]), do: :@ - + def tag([[], ?#]), do: :"#" - + def tag([[], ?*]), do: :* - + def tag([[], ?/]), do: :/ - + def tag([[], ?=]), do: := - + def tag([[], ?>]), do: :> - + def tag([[], ?<]), do: :< - + def tag(_), do: nil end diff --git a/lib/lexer.ex b/lib/lexer.ex index 7a4260b..d76dce8 100644 --- a/lib/lexer.ex +++ b/lib/lexer.ex @@ -9,7 +9,7 @@ defmodule SQL.Lexer do def lex(binary, file \\ "nofile", params \\ 0, binding \\ [], aliases \\ []) do case lex(binary, file, params, binding, aliases, 0, 0, nil, [], nil, [], 0) do {:error, error} -> raise TokenMissingError, [{:snippet, binary} | error] - {"", ^file, params, binding, aliases, _line, _column, nil, [], nil, acc, 0} -> {:ok, %{params: params, binding: binding, aliases: aliases}, acc} + {"", ^file, params, binding, aliases, _line, _column, nil, [], nil, acc, 0} -> {:ok, %{params: params, binding: binding, aliases: aliases, errors: []}, acc} end end def lex("", file, _params, _binding, _aliases, line, column, type, _data, _meta, _acc, _n) when type in ~w[backtick quote double_quote double_braces]a do @@ -82,7 +82,8 @@ defmodule SQL.Lexer do case node(type, line, column, data, meta, file) do {:ident, _, _} = node -> update_state(rest, f, p, b, a, line, column, :fun, [node, node(tag, l, c, value, nil, f)], nil, acc, n, l, c, nil, [], nil) - + {_, [{:type, :operator}|_], _} = node -> + lex(rest, f, params, binding, aliases, l, c, nil, [], nil, [node(tag, l, c, value, nil, f), node|acc], n) {t, m, []=a2} -> lex(rest, f, params, binding, aliases, l, c, nil, [], nil, [{t, m, [node(tag, l, c, value, nil, f)|a2]}|acc], n) end @@ -189,9 +190,6 @@ defmodule SQL.Lexer do def update_state(rest, file, params, binding, aliases, line, column, type, data, meta, [{:dot=t2, m2, []=a}, {tag, _, _}=right|acc], n, l, c, t, d, m) when (type in ~w[ident double_quote bracket dot]a or data==[[], ?*]) and tag in ~w[ident double_quote bracket dot]a do lex(rest, file, params, binding, aliases, l, c, t, d, m, [{t2, m2, [right, node(type, line, column, data, meta, file)|a]}|acc], n) end - def update_state(rest, file, params, [format: true]=binding, aliases, line, column, :double_braces=type, data, meta, acc, n, l, c, t, d, m) do - lex(rest, file, params, binding, aliases, l, c, t, d, m, [node(type, line, column, data, meta, file)|acc], n) - end def update_state(rest, file, params, binding, aliases, line, column, :double_braces=type, data, meta, acc, n, l, c, t, d, m) do params=params+1 lex(rest, file, params, :lists.flatten(binding, [Code.string_to_quoted!(IO.iodata_to_binary(data), file: file, line: line, column: column, columns: true, token_metadata: true, existing_atoms_only: true)]), aliases, l, c, t, d, m, [node(type, line, column, [params], meta, file)|acc], n) @@ -220,9 +218,10 @@ defmodule SQL.Lexer do def node(tag, line, column, [{_, _, _} | _]=data, _meta, file), do: {tag, [type: :expression, line: line, column: column, file: file], data} def node(tag, line, column, data, nil, file) do case tag(data) do + nil -> {tag, [type: :literal, line: line, column: column, file: file], data} {:reserved = k, tag} -> {tag, [type: k, line: line, column: column, file: file], []} {k, t} -> {tag, [type: k, tag: t, line: line, column: column, file: file], data} - _ -> {tag, [type: :literal, line: line, column: column, file: file], data} + tag -> {tag, [type: :operator, line: line, column: column, file: file], []} end end def node(tag, line, column, data, _meta, file), do: {tag, [type: :literal, line: line, column: column, file: file], data} diff --git a/lib/mix/tasks/sql.gen.helpers.ex b/lib/mix/tasks/sql.gen.helpers.ex index ba9ca0a..ee92a65 100644 --- a/lib/mix/tasks/sql.gen.helpers.ex +++ b/lib/mix/tasks/sql.gen.helpers.ex @@ -72,6 +72,7 @@ defmodule Mix.Tasks.Sql.Gen.Helpers do {:json_path_return, [type: :postgres], ["@?"]}, {:ranges_adjacent, [type: :postgres], ["-|-"]}, {:cast, [type: :postgres], ["::"]}, + {:as, [type: :postgres], ["as"]}, ] rules = SQL.BNF.parse(%{ "" => ~w[| LIMIT | ILIKE | BACKWARD | FORWARD | ISNULL | NOTNULL], @@ -99,7 +100,7 @@ defmodule Mix.Tasks.Sql.Gen.Helpers do whitespace = Enum.map(rules.terminals[""], fn <> -> c end) newline = Enum.map(rules.terminals[""], fn <> -> c end) reserved = rules.keywords[""] ++ rules.keywords[""] - create_file("lib/helpers.ex", helpers_template([mod: SQL.Lexer, reserved: Enum.uniq(reserved), non_reserved: Enum.uniq(rules.keywords[""]), nested_start: ~c"#{elem(exprs, 1)}", nested_end: ~c"#{elem(exprs, 2)}", special_characters: ~c"#{Enum.uniq(Enum.map(rules.special_characters, &elem(&1, 1)))}", operators: Enum.uniq(Enum.flat_map(rules.operators, &elem(&1, 1))), digits: ~c"#{rules.digits[""]}", exprs: exprs, space: space, whitespace: whitespace, newline: newline])) + create_file("lib/helpers.ex", helpers_template([mod: SQL.Lexer, reserved: Enum.uniq(reserved), non_reserved: Enum.uniq(rules.keywords[""]), nested_start: ~c"#{elem(exprs, 1)}", nested_end: ~c"#{elem(exprs, 2)}", special_characters: ~c"#{Enum.uniq(Enum.map(rules.special_characters, &elem(&1, 1)))}", operators: Enum.uniq(Enum.flat_map(rules.operators, &elem(&1, 1))), digits: ~c"#{rules.digits[""]}", exprs: exprs, space: space, whitespace: whitespace, newline: newline]), force: true) end embed_template(:helpers, """ diff --git a/lib/mix/tasks/sql.gen.test.ex b/lib/mix/tasks/sql.gen.test.ex index da2a29f..1795115 100644 --- a/lib/mix/tasks/sql.gen.test.ex +++ b/lib/mix/tasks/sql.gen.test.ex @@ -1,70 +1,77 @@ # SPDX-License-Identifier: Apache-2.0 # SPDX-FileCopyrightText: 2025 DBVisor +if Code.ensure_loaded?(:yamerl) do + defmodule Mix.Tasks.Sql.Gen.Test do + use Mix.Task + import Mix.Generator + @moduledoc since: "0.2.0" -defmodule Mix.Tasks.Sql.Gen.Test do - use Mix.Task - import Mix.Generator - @moduledoc since: "0.2.0" - - @shortdoc "Generates test from the BNF rules" - def run([base]) do - create_file("test/conformance/e_test.exs", test_template([mod: SQL.Conformance.ETest, dir: Path.join(base, "E")])) - create_file("test/conformance/f_test.exs", test_template([mod: SQL.Conformance.FTest, dir: Path.join(base, "F")])) - create_file("test/conformance/s_test.exs", test_template([mod: SQL.Conformance.STest, dir: Path.join(base, "S")])) - create_file("test/conformance/t_test.exs", test_template([mod: SQL.Conformance.TTest, dir: Path.join(base, "T")])) - end + @shortdoc "Generates test from the BNF rules" + def run([base]) do + create_file("test/conformance/e_test.exs", test_template([mod: SQL.Conformance.ETest, dir: Path.join(base, "E")]), force: true) + create_file("test/conformance/f_test.exs", test_template([mod: SQL.Conformance.FTest, dir: Path.join(base, "F")]), force: true) + create_file("test/conformance/s_test.exs", test_template([mod: SQL.Conformance.STest, dir: Path.join(base, "S")]), force: true) + create_file("test/conformance/t_test.exs", test_template([mod: SQL.Conformance.TTest, dir: Path.join(base, "T")]), force: true) + end - def generate_test(dir) do - for path <- File.ls!(dir), path =~ ".tests.yml", [{~c"feature", feature}, {~c"id", id}, {~c"sql", sql}] <- :yamerl.decode_file(to_charlist(Path.join(dir, path))) do - statements = if is_list(hd(sql)), do: sql, else: [sql] - statements = Enum.map(statements, &String.replace(to_string(&1), ~r{(VARING)}, "VARYING")) - {"#{feature} #{id}", Enum.map(statements, &{trim(&1), &1})} + def generate_test(dir) do + for path <- File.ls!(dir), path =~ ".tests.yml", [{~c"feature", feature}, {~c"id", id}, {~c"sql", sql}] <- :yamerl.decode_file(to_charlist(Path.join(dir, path))) do + statements = if is_list(hd(sql)), do: sql, else: [sql] + statements = Enum.map(statements, &String.replace(to_string(&1), ~r{(VARING)}, "VARYING")) + {"#{feature} #{id}", Enum.map(statements, &{trim(&1), &1})} + end end + + def trim(value) do + value + |> String.replace(~r{\(\s+\b}, &String.replace(&1, " ", "")) + |> String.replace(~r{\(\s+'}, &String.replace(&1, " ", "")) + |> String.replace(~r{\(\s+"}, &String.replace(&1, " ", "")) + |> String.replace(~r{\(\s+\*}, &String.replace(&1, " ", "")) + |> String.replace(~r{\b\s+\,}, &String.replace(&1, " ", "")) + |> String.replace(~r{\)\s+\,}, &String.replace(&1, " ", "")) + |> String.replace(~r{\'\s+\,}, &String.replace(&1, " ", "")) + |> String.replace(~r{\b\s+\)}, &String.replace(&1, " ", "")) + |> String.replace(~r{'\s+\)}, &String.replace(&1, " ", "")) + |> String.replace(~r{\*\s+\)}, &String.replace(&1, " ", "")) + |> String.replace(~r{\)\s+\)}, &String.replace(&1, " ", "")) + |> String.replace(~r{(A)\s\+\d}, &Enum.join(Regex.split(~r{\d}, &1, include_captures: true, trim: true), " ")) + |> String.replace(~r{\W(SELECT|REFERENCES|INSERT|UPDATE|IN|MYTEMP)\(}, &Enum.join(Regex.split(~r{\(}, &1, include_captures: true, trim: true), " ")) + |> String.replace(~r{^(SELECT)\(}, &Enum.join(Regex.split(~r{\(}, &1, include_captures: true, trim: true), " ")) + |> String.replace(~r{\s+\.\s+}, &String.replace(&1, " ", "")) + |> String.replace(~r{\d\s(\+|\-)\d}, &Enum.join(Enum.map(Regex.split(~r{\+|\-}, &1, include_captures: true, trim: true), fn x -> String.trim(x) end), " ")) + |> String.trim() end - def trim(value) do - value - |> String.replace(~r{\(\s+\b}, &String.replace(&1, " ", "")) - |> String.replace(~r{\(\s+'}, &String.replace(&1, " ", "")) - |> String.replace(~r{\(\s+"}, &String.replace(&1, " ", "")) - |> String.replace(~r{\(\s+\*}, &String.replace(&1, " ", "")) - |> String.replace(~r{\b\s+\,}, &String.replace(&1, " ", "")) - |> String.replace(~r{\)\s+\,}, &String.replace(&1, " ", "")) - |> String.replace(~r{\'\s+\,}, &String.replace(&1, " ", "")) - |> String.replace(~r{\b\s+\)}, &String.replace(&1, " ", "")) - |> String.replace(~r{'\s+\)}, &String.replace(&1, " ", "")) - |> String.replace(~r{\*\s+\)}, &String.replace(&1, " ", "")) - |> String.replace(~r{\)\s+\)}, &String.replace(&1, " ", "")) - |> String.replace(~r{(A)\s\+\d}, &Enum.join(Regex.split(~r{\d}, &1, include_captures: true, trim: true), " ")) - |> String.replace(~r{\W(SELECT|REFERENCES|INSERT|UPDATE|IN|MYTEMP)\(}, &Enum.join(Regex.split(~r{\(}, &1, include_captures: true, trim: true), " ")) - |> String.replace(~r{^(SELECT)\(}, &Enum.join(Regex.split(~r{\(}, &1, include_captures: true, trim: true), " ")) - |> String.replace(~r{\s+\.\s+}, &String.replace(&1, " ", "")) - |> String.replace(~r{\d\s(\+|\-)\d}, &Enum.join(Enum.map(Regex.split(~r{\+|\-}, &1, include_captures: true, trim: true), fn x -> String.trim(x) end), " ")) - |> String.trim() - end + embed_template(:test, """ + # SPDX-License-Identifier: Apache-2.0 + # SPDX-FileCopyrightText: 2025 DBVisor - embed_template(:test, """ - # SPDX-License-Identifier: Apache-2.0 - # SPDX-FileCopyrightText: 2025 DBVisor + defmodule <%= inspect @mod %>.Adapter do + use SQL.Token - defmodule <%= inspect @mod %>.Adapter do - use SQL.Token + def token_to_string(value, mod \\\\ __MODULE__) + def token_to_string(value, _mod) when is_atom(value), do: String.upcase(Atom.to_string(value)) + def token_to_string(token, mod), do: SQL.Adapters.ANSI.token_to_string(token, mod) - def token_to_string(value, mod \\\\ __MODULE__) - def token_to_string(value, _mod) when is_atom(value), do: String.upcase(Atom.to_string(value)) - def token_to_string(token, mod), do: SQL.Adapters.ANSI.token_to_string(token, mod) - end - defmodule <%= inspect @mod %> do - use ExUnit.Case, async: true - use SQL, adapter: <%= inspect @mod %>.Adapter + def to_iodata(value, _context, _indent) when is_atom(value) do + String.upcase(Atom.to_string(value)) + end + def to_iodata(token, context, indent), do: SQL.Adapters.ANSI.to_iodata(token, context, indent) + def to_iodata(tokens, context, indent, acc), do: SQL.Adapters.ANSI.to_iodata(tokens, context, indent, acc) + end + defmodule <%= inspect @mod %> do + use ExUnit.Case, async: true + use SQL, adapter: <%= inspect @mod %>.Adapter - <%= for {name, statements} <- generate_test(@dir) do %> - test <%= inspect name %> do - <%= for {left, right} <- statements do %> - assert ~s{<%= left %>} == to_string(~SQL[<%= right %>]) + <%= for {name, statements} <- generate_test(@dir) do %> + test <%= inspect name %> do + <%= for {left, right} <- statements do %> + assert ~s{<%= left %>} == to_string(~SQL[<%= right %>]) + <% end %> + end <% end %> end - <% end %> + """) end - """) end diff --git a/lib/mix/tasks/sql.get.ex b/lib/mix/tasks/sql.get.ex new file mode 100644 index 0000000..8c1983d --- /dev/null +++ b/lib/mix/tasks/sql.get.ex @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 DBVisor + +defmodule Mix.Tasks.Sql.Get do + use Mix.Task + import SQL + import Mix.Generator + @moduledoc since: "0.3.0" + + defguard is_postgres(value) when value in [Ecto.Adapters.Postgres, Postgrex] + defguard is_mysql(value) when value in [Ecto.Adapters.MyXQL, MyXQL] + defguard is_tds(value) when value in [Ecto.Adapters.Tds, Tds] + defguard is_sqlite(value) when value in [Ecto.Adapters.SQLite3, Exqlite] + + @shortdoc "Generates a sql.lock" + def run(args) do + app = Mix.Project.config()[:app] + Application.load(app) + repos = Application.get_env(app, :ecto_repos) + Mix.Task.run("app.config", args) + Application.ensure_all_started(:ecto_sql, :permanent) + lock = Enum.reduce(repos, %{}, fn repo, acc -> + repo.__adapter__().ensure_all_started(repo.config(), []) + repo.start_link(repo.config()) + Map.merge(acc, to_lock(repo, repo.__adapter__()), fn _, l, r -> Enum.uniq(:lists.flatten(l, r)) end) + end) + create_file("sql.lock", lock_template(lock: lock), force: true) + end + + def get(repo, sql) do + {:ok, %{columns: columns, rows: rows}} = repo.query(to_string(sql), []) + columns = Enum.map(columns, &String.to_atom(String.downcase(&1))) + Enum.map(rows, &Map.new(Enum.zip(columns, &1))) + end + + embed_template(:lock, """ + <%= inspect @lock, pretty: true, limit: :infinity %> + """) + + def to_lock(repo, value) when not is_sqlite(value) do + %{columns: get(repo, to_query(value, :columns)), tables: get(repo, to_query(value, :tables))} + end + def to_lock(repo, value) when is_sqlite(value) do + tables = get(repo, to_query(value, :tables)) + %{columns: tables, tables: tables} + end + + def to_query(value, :tables) when is_postgres(value), do: ~SQL"select * from information_schema.tables where table_schema not in ('information_schema', 'pg_catalog')" + def to_query(value, :columns) when is_postgres(value), do: ~SQL"select * from information_schema.columns where table_schema not in ('information_schema', 'pg_catalog')" + def to_query(value, :tables) when is_tds(value), do: ~SQL"select * from information_schema.tables where table_schema not in ('information_schema', 'pg_catalog')" + def to_query(value, :columns) when is_tds(value), do: ~SQL"select * from information_schema.columns where table_schema not in ('information_schema', 'pg_catalog')" + def to_query(value, :tables) when is_mysql(value), do: ~SQL"SELECT * FROM information_schema.tables WHERE table_schema not in('mysql', 'performance_schema', 'sys')" + def to_query(value, :columns) when is_mysql(value), do: ~SQL"SELECT * FROM information_schema.columns WHERE table_schema not in('mysql', 'performance_schema', 'sys')" + def to_query(value, :tables) when is_sqlite(value), do: ~SQL"SELECT * FROM sqlite_master JOIN pragma_table_info (sqlite_master.name)" +end diff --git a/lib/parser.ex b/lib/parser.ex index ff83927..d51b288 100644 --- a/lib/parser.ex +++ b/lib/parser.ex @@ -3,129 +3,138 @@ defmodule SQL.Parser do @moduledoc false - @compile {:inline, parse: 6, __parse__: 2} + @compile {:inline, validate: 3, parse: 7, __parse__: 2} def parse(tokens, context) do - parse(tokens, context, [], [], [], []) + parse(tokens, context, [], [], [], [], []) end - def parse([], context, [], [], [], tokens) do - {:ok, context, tokens} + def parse([], context, [], [], [], tokens, errors) do + {:ok, Map.update!(context, :errors, &:lists.flatten(errors, &1)), tokens} end - def parse([], context, [], [], acc, tokens) do - {:ok, context, :lists.flatten(sort(acc), tokens)} + def parse([], context, [], [], acc, tokens, errors) do + {:ok, Map.update!(context, :errors, &:lists.flatten(errors, &1)), :lists.flatten(sort(acc), tokens)} end - def parse([], context, a, acc, [], []) do + def parse([], context, a, acc, [], [], errors) do {a, context} = __parse__(a, context) - {:ok, context, [a|acc]} + {:ok, Map.update!(context, :errors, &:lists.flatten(errors, &1)), [a|acc]} end - def parse([], context, unit, acc, root, []) do - {:ok, context, :lists.flatten([unit|acc], root)} + def parse([], context, unit, acc, root, [], errors) do + {:ok, Map.update!(context, :errors, &:lists.flatten(errors, &1)), :lists.flatten([unit|acc], root)} end - def parse([{:with=t, m, []=unit}|tokens], context, a, acc, root, acc2) do + def parse([{:with=t, m, []=unit}|tokens], context, a, acc, root, acc2, errors) do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{t, m, [:lists.flatten(a, acc),sort(root)|unit]}], acc2) + parse(tokens, context, unit, unit, [{t, m, [:lists.flatten(a, acc),sort(root)|unit]}], acc2, errors) end - def parse([{:comma=t, m, []=unit}|tokens], context, a, acc, root, acc2) do + def parse([{:comma, _, []} = node|tokens], context, a, acc, root, acc2, errors) do {a, context} = __parse__(a, context) - parse(tokens, context, unit, [{t,m,a}|acc], root, acc2) + parse(tokens, context, [node], :lists.flatten(a, acc), root, acc2, errors) end - def parse([{:colon=t, tm, ta}|tokens], context, []=unit, []=acc, root, acc2) do + def parse([{:colon=t, tm, ta}|tokens], context, []=unit, []=acc, root, acc2, errors) do {:ok, context, ta} = parse(ta, context) - parse(tokens, context, unit, acc, [], [{t, tm, ta},sort(root)|acc2]) + parse(tokens, context, unit, acc, [], [{t, tm, ta},sort(root)|acc2], errors) end - def parse([l,{t,tm,[]=ta},r,{t3,t3m,t3a},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[from in]a and t3 in ~w[backward forward]a do - parse(tokens, context, unit, acc, [{f,fm,[{t3,t3m,[r|t3a]},{t,tm,[l|ta]}|fa]}|root], acc2) + def parse([l,{t,tm,[]=ta},r,{t3,t3m,t3a},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[from in]a and t3 in ~w[backward forward]a do + parse(tokens, context, unit, acc, [{f,fm,[{t3,t3m,[r|t3a]},{t,tm,[l|ta]}|fa]}|root], acc2, errors) end - def parse([l,{t,tm,[]=ta},r,{_,[_,{:tag, t3}|_]=t3m,_},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[from in]a and t3 in ~w[absolute relative]a do - parse(tokens, context, unit, acc, [{f,fm,[{t3,t3m,[r]},{t,tm,[l|ta]}|fa]}|root], acc2) + def parse([l,{t,tm,[]=ta},r,{_,[_,{:tag, t3}|_]=t3m,_},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[from in]a and t3 in ~w[absolute relative]a do + parse(tokens, context, unit, acc, [{f,fm,[{t3,t3m,[r]},{t,tm,[l|ta]}|fa]}|root], acc2, errors) end - def parse([r,{t,tm,[]=ta},{:ident,[_,{:tag, l}|_]=lm,_},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[from in]a do - parse(tokens, context, unit, acc, [{f,fm,[{l,lm,[{t,tm,[r|ta]}]}|fa]}|root], acc2) + def parse([r,{t,tm,[]=ta},{:ident,[_,{:tag, l}|_]=lm,_},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[from in]a do + parse(tokens, context, unit, acc, [{f,fm,[{l,lm,[{t,tm,[r|ta]}]}|fa]}|root], acc2, errors) end - def parse([r,{t,tm,[]=ta},{:numeric,_,_}=l,{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[from in]a do - parse(tokens, context, unit, acc, [{f,fm,[l,{t,tm,[r|ta]}|fa]}|root], acc2) + def parse([r,{t,tm,[]=ta},{:numeric,_,_}=l,{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[from in]a do + parse(tokens, context, unit, acc, [{f,fm,[l,{t,tm,[r|ta]}|fa]}|root], acc2, errors) end - def parse([r,{t,tm,[]=ta},{l,lm,la},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[from in]a do - parse(tokens, context, unit, acc, [{f,fm,[{l,lm, [{t,tm,[r|ta]}|la]}|fa]}|root], acc2) + def parse([r,{t,tm,[]=ta},{l,lm,la},{:fetch=f,fm,[]=fa}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[from in]a do + parse(tokens, context, unit, acc, [{f,fm,[{l,lm, [{t,tm,[r|ta]}|la]}|fa]}|root], acc2, errors) end - def parse([{t,m,[]=unit}|tokens], context, a, acc, root, acc2) when t in ~w[by on]a do + def parse([{t,m,[]=unit}|tokens], context, a, acc, root, acc2, errors) when t in ~w[by on]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, [{t,m,:lists.flatten(a, acc)}], root, acc2) + parse(tokens, context, unit, [{t,m,:lists.flatten(a, acc)}], root, acc2, errors) end - def parse([{_,[_,{:tag,t}|_]=m,_}, node|tokens], context, unit, acc, root, acc2) when t in ~w[asc desc]a do - parse(tokens, context, [{t,m,[node]}|unit], acc, root, acc2) + def parse([{_,[_,{:tag,t}|_]=m,_}, node|tokens], context, unit, acc, root, acc2, errors) when t in ~w[asc desc]a do + parse(tokens, context, [{t,m,[node]}|unit], acc, root, acc2, errors) end - def parse([{:paren=r,rm,ra}, {:all=a, am, []=aa}, {t, tm, []=ta}, {:paren=l, lm, la}|tokens], context, unit, acc, root, acc2) when t in ~w[except intersect union]a do + def parse([{:paren=r,rm,ra}, {:all=a, am, []=aa}, {t, tm, []=ta}, {:paren=l, lm, la}|tokens], context, unit, acc, root, acc2, errors) when t in ~w[except intersect union]a do {:ok, context, la} = parse(la, context) {:ok, context, ra} = parse(ra, context) - parse(tokens, context, unit, acc, [{t,tm,[{l,lm,la},{a, am, [{r, rm, ra}|aa]}|ta]}|root], acc2) + parse(tokens, context, unit, acc, [{t,tm,[{l,lm,la},{a, am, [{r, rm, ra}|aa]}|ta]}|root], acc2, errors) end - def parse([{:paren=r,rm,ra}, {t, tm, []=ta}, {:paren=l, lm, la}|tokens], context, unit, acc, root, acc2) when t in ~w[except intersect union]a do + def parse([{:paren=r,rm,ra}, {t, tm, []=ta}, {:paren=l, lm, la}|tokens], context, unit, acc, root, acc2, errors) when t in ~w[except intersect union]a do {:ok, context, la} = parse(la, context) {:ok, context, ra} = parse(ra, context) - parse(tokens, context, unit, acc, [{t,tm,[{l,lm,la},{r, rm, ra}|ta]}|root], acc2) + parse(tokens, context, unit, acc, [{t,tm,[{l,lm,la},{r, rm, ra}|ta]}|root], acc2, errors) end - def parse([{a, am, []=aa}, {t, tm, []=ta}, {:paren=l, lm, la}|tokens], context, unit, acc, root, acc2) when t in ~w[except intersect union]a and a in ~w[all distinct]a do + def parse([{a, am, []=aa}, {t, tm, []=ta}, {:paren=l, lm, la}|tokens], context, unit, acc, root, acc2, errors) when t in ~w[except intersect union]a and a in ~w[all distinct]a do {:ok, context, la} = parse(la, context) - parse(tokens, context, unit, acc, [{t,tm,[{l, lm, la},{a, am, [sort(root)|aa]}|ta]}], acc2) + parse(tokens, context, unit, acc, [{t,tm,[{l, lm, la},{a, am, [sort(root)|aa]}|ta]}], acc2, errors) end - def parse([{t, tm, []=ta}, {:paren=r, rm, ra}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[except intersect union]a do + def parse([{t, tm, []=ta}, {:paren=r, rm, ra}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[except intersect union]a do {:ok, context, ra} = parse(ra, context) - parse(tokens, context, unit, acc, [{t,tm,[{r, rm, ra}, sort(root)|ta]}], acc2) + parse(tokens, context, unit, acc, [{t,tm,[{r, rm, ra}, sort(root)|ta]}], acc2, errors) end - def parse([{a, am, []=aa}, {t, tm, []=ta}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[except intersect union]a and a in ~w[all distinct]a do + def parse([{a, am, []=aa}, {t, tm, []=ta}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[except intersect union]a and a in ~w[all distinct]a do {:ok, context, la} = parse(tokens, context) - parse([], context, unit, acc, [{t,tm,[la,{a,am,[sort(root)|aa]}|ta]}], acc2) + parse([], context, unit, acc, [{t,tm,[la,{a,am,[sort(root)|aa]}|ta]}], acc2, errors) end - def parse([{t, tm, []=ta}|tokens], context, []=unit, []=acc, root, acc2) when t in ~w[except intersect union]a do + def parse([{t, tm, []=ta}|tokens], context, []=unit, []=acc, root, acc2, errors) when t in ~w[except intersect union]a do {:ok, context, la} = parse(tokens, context) - parse([], context, unit, acc, [{t,tm,[la, sort(root)|ta]}], acc2) + parse([], context, unit, acc, [{t,tm,[la, sort(root)|ta]}], acc2, errors) end - def parse([{:join=t,m,[]=unit}, {:outer=o, om, oa}, {l, lm, la}, {:natural=n, nm, na}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2) when l in ~w[left right full]a and tag in ~w[double_quote bracket dot ident as paren]a do + def parse([{:join=t,m,[]=unit}, {:outer=o, om, oa}, {l, lm, la}, {:natural=n, nm, na}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2, errors) when l in ~w[left right full]a and tag in ~w[double_quote bracket dot ident as paren]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{n, nm, [{l, lm, [{o, om, [{t,m,:lists.flatten(a, acc)}|oa]}|la]}|na]}|root], acc2) + node = {t,m,:lists.flatten(a, acc)} + parse(tokens, context, unit, unit, [{n, nm, [{l, lm, [{o, om, [node|oa]}|la]}|na]}|root], acc2, validate(node, context, errors)) end - def parse([{:join=t,m,[]=unit}, {:outer=o, om, oa}, {l, lm, la}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2) when l in ~w[left right full]a and tag in ~w[double_quote bracket dot ident as paren]a do + def parse([{:join=t,m,[]=unit}, {:outer=o, om, oa}, {l, lm, la}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2, errors) when l in ~w[left right full]a and tag in ~w[double_quote bracket dot ident as paren]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{l, lm, [{o, om, [{t,m,:lists.flatten(a, acc)}|oa]}|la]}|root], acc2) + node = {t,m,:lists.flatten(a, acc)} + parse(tokens, context, unit, unit, [{l, lm, [{o, om, [node|oa]}|la]}|root], acc2, validate(node, context, errors)) end - def parse([{:join=t,m,[]=unit}, {:inner=i, im, ia}, {:natural=n, nm, []=na}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2) when tag in ~w[double_quote bracket dot ident as paren]a do + def parse([{:join=t,m,[]=unit}, {:inner=i, im, ia}, {:natural=n, nm, []=na}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2, errors) when tag in ~w[double_quote bracket dot ident as paren]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{n, nm, [{i, im, [{t,m,:lists.flatten(a, acc)}|ia]}|na]}|root], acc2) + node = {t,m,:lists.flatten(a, acc)} + parse(tokens, context, unit, unit, [{n, nm, [{i, im, [node|ia]}|na]}|root], acc2, validate(node, context, errors)) end - def parse([{:join=t,m,[]=unit}, {l, lm, []=la}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2) when l in ~w[inner left right full natural cross]a and tag in ~w[double_quote bracket dot ident as paren]a do + def parse([{:join=t,m,[]=unit}, {l, lm, []=la}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2, errors) when l in ~w[inner left right full natural cross]a and tag in ~w[double_quote bracket dot ident as paren]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{l, lm, [{t,m,:lists.flatten(a, acc)}|la]}|root], acc2) + node = {t,m,:lists.flatten(a, acc)} + parse(tokens, context, unit, unit, [{l, lm, [node|la]}|root], acc2, validate(node, context, errors)) end - def parse([{:join=t,m,[]=unit}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2) when tag in ~w[double_quote bracket dot ident as paren]a do + def parse([{:join=t,m,[]=unit}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2, errors) when tag in ~w[double_quote bracket dot ident as paren]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{t,m,:lists.flatten(a, acc)}|root], acc2) + node = {t,m,:lists.flatten(a, acc)} + parse(tokens, context, unit, unit, [node|root], acc2, validate(node, context, errors)) end - def parse([{:from=t,m,[]=unit}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2) when tag in ~w[double_quote bracket dot ident as]a do + def parse([{:from=t,m,[]=unit}|tokens], context, [{tag,_,_}|_]=a, acc, root, acc2, errors) when tag in ~w[double_quote bracket dot ident as binding]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{t,m,:lists.flatten(a, acc)}|root], acc2) + node = {t,m,:lists.flatten(a, acc)} + parse(tokens, context, unit, unit, [node|root], acc2, validate(node, context, errors)) end - def parse([{t,m,[]=unit}|tokens], context, a, acc, root, acc2) when t in ~w[select where group having order limit offset]a do + def parse([{t,m,[]=unit}|tokens], context, a, acc, root, acc2, errors) when t in ~w[select where group having order limit offset]a do {a, context} = __parse__(a, context) - parse(tokens, context, unit, unit, [{t,m,:lists.flatten(a, acc)}|root], acc2) + parse(tokens, context, unit, unit, [{t,m,:lists.flatten(a, acc)}|root], acc2, errors) end - def parse([{t,m,[{:paren=t2,m2,a2}]}|tokens], context, unit, acc, root, acc2) do + def parse([{t,m,[{:paren=t2,m2,a2}]}|tokens], context, unit, acc, root, acc2, errors) do {:ok, context, a2} = parse(a2, context) - parse(tokens, context, [{t,m,[{t2,m2,a2}]}|unit], acc, root, acc2) + parse(tokens, context, [{t,m,[{t2,m2,a2}]}|unit], acc, root, acc2, errors) end - def parse([{t,m,[r, {:paren=t2,m2,a2}]}|tokens], context, unit, acc, root, acc2) do + def parse([{t,m,[r, {:paren=t2,m2,a2}]}|tokens], context, unit, acc, root, acc2, errors) do {:ok, context, a2} = parse(a2, context) - parse(tokens, context, [{t,m,[r, {t2,m2,a2}]}|unit], acc, root, acc2) + parse(tokens, context, [{t,m,[r, {t2,m2,a2}]}|unit], acc, root, acc2, errors) end - def parse([{:paren=t,m,a}|tokens], context, unit, acc, root, acc2) do + def parse([{:paren=t,m,a}|tokens], context, unit, acc, root, acc2, errors) do {:ok, context, a} = parse(a, context) - parse(tokens, context, [{t,m,a}|unit], acc, root, acc2) + parse(tokens, context, [{t,m,a}|unit], acc, root, acc2, errors) end - def parse([{tag,_,_}=node|tokens], context, unit, acc, root, acc2) when tag in ~w[numeric ident quote double_quote backtick bracket dot binding]a do - parse(tokens, context, [node|unit], acc, root, acc2) + def parse([{:table=tt,mt,at}, {:create=tc,mc,ac}|tokens], context, unit, acc, root, acc2, errors) do + parse(tokens, context, at, acc, [{tc,mc,[{tt,mt,:lists.flatten(unit, acc)}|ac]}|root], acc2, errors) end - def parse([node|tokens], context, unit, acc, root, acc2) do - parse(tokens, context, [node|unit], acc, root, acc2) + def parse([{tag,_,_}=node|tokens], context, unit, acc, root, acc2, errors) when tag in ~w[numeric ident quote double_quote backtick bracket dot binding]a do + parse(tokens, context, [node|unit], acc, root, acc2, errors) + end + def parse([node|tokens], context, unit, acc, root, acc2, errors) do + parse(tokens, context, [node|unit], acc, root, acc2, errors) end def __parse__([l,{t,m,a},r|[{c,_,[]}|_]=rest],context) when c in ~w[and or]a, do: __parse__([{t,m,[l,r|a]}|rest],context) @@ -144,11 +153,42 @@ defmodule SQL.Parser do def __parse__([b,{:is=c,cm,[]=ca},{t,_,[]}=node|rest],context) when t in ~w[false true unknown null binding]a, do: __parse__([{c,cm,[b,node|ca]}|rest],context) def __parse__([b,{:not=n,nm,[]=na},{:in=c,cm,[]=ca},node|rest],context), do: __parse__([{n,nm,[b,{c,cm,[node|ca]}|na]}|rest],context) def __parse__([b,{:in=c,cm,[]=ca},node|rest],context), do: __parse__([{c,cm,[b,node|ca]}|rest],context) - def __parse__([b,{c,cm,[]=ca},n|rest],context) when c in ~w[ilike like <= >= < > <> / * + - =]a, do: __parse__([{c,cm,[b,n|ca]}|rest],context) + def __parse__([b,{c,cm,[]=ca},n|rest],context) when c in ~w[as ilike like <= >= < > <> / * + - =]a, do: __parse__([{c,cm,[b,n|ca]}|rest],context) + def __parse__([{t,m,[]=a},b,{:as=c,cm,[]=ca},n|rest],context), do: __parse__([{t,m,[{c,cm,[b,n|ca]}|a]}|rest],context) def __parse__([{tl,_,a}=l,{tr,_,as}=r],context) when tl in ~w[ident double_quote bracket dot binding]a and tr in ~w[ident double_quote bracket dot binding]a, do: __parse__([{:as, [], [l,r]}], Map.update!(context, :aliases, &[{as, a}|&1])) def __parse__([{tl,_,la}=l,{:as=tr,rm,ra}],context) when tl in ~w[ident double_quote bracket dot binding]a, do: __parse__([{:as=tr,rm,[l|ra]}], Map.update!(context, :aliases, &[{la, nil}|&1])) + def __parse__([l,{:comma=tc,mc,[]=ac}|unit],context), do: {[{tc,mc,[l|ac]}|unit], context} def __parse__(unit, context), do: {unit, context} @order %{select: 0, from: 1, join: 2, where: 3, group: 4, having: 5, window: 6, order: 7, limit: 8, offset: 9, fetch: 10} def sort(acc), do: Enum.sort_by(acc, fn {tag, _, _} -> Map.get(@order, tag) end, :asc) + + def validate(_, %{sql_lock: nil}, errors), do: errors + def validate({tag, _, _}, %{sql_lock: %{tables: []}}, errors) when tag in ~w[from join]a, do: errors + def validate({tag, _meta, values}, %{sql_lock: %{tables: tables}}, errors) when tag in ~w[from join]a do + values + |> Enum.reduce([], fn + {:paren, _, _}, acc -> acc + {:on, _, _}, acc -> acc + {tag, _, _}=node, acc when tag in ~w[ident double_quote]a -> validate_table(tables, node, acc) + {:as, _, [{tag, _, _}=node, _]}, acc when tag in ~w[ident double_quote]a -> validate_table(tables, node, acc) + {:dot, _, [_, {tag, _, _}=node]}, acc when tag in ~w[ident double_quote]a -> validate_table(tables, node, acc) + {:dot, _, [_, {:bracket, _, [{:ident, _, _}=node]}]}, acc -> validate_table(tables, node, acc) + {:comma, _, [{:dot, _, [_, {:bracket, _, [{:ident, _, _}=node]}]}]}, acc -> validate_table(tables, node, acc) + {:comma, _, [{:dot, _, [_, {tag, _, _}=node]}]}, acc when tag in ~w[ident double_quote]a -> validate_table(tables, node, acc) + {:comma, _, [{:as, _, [{tag, _, _}=node, _]}]}, acc when tag in ~w[ident double_quote]a -> validate_table(tables, node, acc) + {:comma, _, [{tag, _, _}=node]}, acc when tag in ~w[ident double_quote]a -> validate_table(tables, node, acc) + end) + |> case do + [] -> errors + values -> [values|errors] + end + end + + def validate_table(tables, {_, _, value}=node, acc) do + case Enum.find(tables, false, fn %{table_name: {_, _, fun}} -> fun.(value) end) do + true -> acc + false -> [node|acc] + end + end end diff --git a/lib/sql.ex b/lib/sql.ex index 40a1d7b..399111e 100644 --- a/lib/sql.ex +++ b/lib/sql.ex @@ -13,7 +13,12 @@ defmodule SQL do quote bind_quoted: [opts: opts] do @doc false import SQL - @sql_adapter opts[:adapter] + if File.exists?(Path.relative_to_cwd("sql.lock")) do + Module.put_attribute(__MODULE__, :sql_lock, build_lock()) + else + IO.warn("Could not find a sql.lock, please run mix sql.get") + end + Module.put_attribute(__MODULE__, :sql_adapter, opts[:adapter]) def sql_config, do: unquote(opts) end end @@ -21,7 +26,7 @@ defmodule SQL do defstruct [tokens: [], params: [], module: nil, id: nil, string: nil, inspect: nil] defimpl Inspect, for: SQL do - def inspect(sql, _opts), do: ~s[~SQL"""\n#{sql.inspect}\n"""] + def inspect(sql, _opts), do: sql.inspect end defimpl String.Chars, for: SQL do @@ -46,9 +51,13 @@ defmodule SQL do ## Examples iex(1)> ~SQL"from users select id, email" - ~SQL"\"\" - from users select id, email - "\"\" + ~SQL\"\"\" + select + id, + email + from + users + \"\"\" """ @doc since: "0.1.0" defmacro sigil_SQL(left \\ [], right, modifiers) do @@ -57,23 +66,31 @@ defmodule SQL do @doc false @doc since: "0.1.0" - def parse(binary) do - {:ok, context, tokens} = SQL.Lexer.lex(binary, __ENV__.file, 0, [format: true]) - {:ok, _context, tokens} = SQL.Parser.parse(tokens, context) - ANSI.token_to_string(tokens) + def parse(binary, opts \\ [format: true, module: ANSI, sql_lock: nil]) do + {:ok, context, tokens} = SQL.Lexer.lex(binary) + {:ok, context, tokens} = SQL.Parser.parse(tokens, Map.merge(context, Map.new(opts))) + iodata = context.module.to_iodata(tokens, context, 0, []) + if context.errors != [], do: IO.warn(IO.ANSI.format([?\n, format_error(context.errors), " \n ", IO.ANSI.format(iodata), ?\n])) + IO.iodata_to_binary(IO.ANSI.format(iodata, false)) end @doc false def build(left, {:<<>>, _, _} = right, _modifiers, env) do - module = if env.module, do: Module.get_attribute(env.module, :sql_adapter, ANSI), else: ANSI + module = if env.module, do: Module.get_attribute(env.module, :sql_adapter, ANSI), else: Application.get_env(:sql, :adapter, ANSI) + sql_lock = if env.module, do: Module.get_attribute(env.module, :sql_lock) sql = struct(SQL, module: env.module) + stack = if env.function do + {env.module, elem(env.function, 0), elem(env.function, 1), [file: Path.relative_to_cwd(env.file), line: env.line]} + else + {env.module, env.function, 0, [file: Path.relative_to_cwd(env.file), line: env.line]} + end case build(left, right) do {:static, data} -> id = id(data) {:ok, context, tokens} = SQL.Lexer.lex(data, env.file) - {:ok, context, t} = SQL.Parser.parse(tokens, context) - string = IO.iodata_to_binary(module.token_to_string(t)) - sql = %{sql | tokens: t, string: string, inspect: data, id: id} + {:ok, context, t} = SQL.Parser.parse(tokens, Map.merge(context, %{sql_lock: sql_lock, module: module})) + {string, inspect} = format(t, context, stack) + sql = %{sql | tokens: t, string: string, inspect: inspect, id: id} case context.binding do [] -> Macro.escape(sql) params -> @@ -84,14 +101,15 @@ defmodule SQL do {:dynamic, data} -> sql = %{sql | id: id(data)} - quote bind_quoted: [left: Macro.unpipe(left), right: right, file: env.file, data: data, sql: Macro.escape(sql), env: Macro.escape(env), module: module] do + quote bind_quoted: [left: Macro.unpipe(left), right: right, file: env.file, data: data, sql: Macro.escape(sql), env: Macro.escape(env), module: module, sql_lock: Macro.escape(sql_lock), stack: Macro.escape(stack)] do {t, p} = Enum.reduce(left, {[], []}, fn {[], 0}, acc -> acc {v, 0}, {t, p} -> {t ++ v.tokens, p ++ v.params} end) {:ok, context, tokens} = tokens(right, file, length(p), sql.id) tokens = t ++ tokens - %{sql | params: :lists.flatten(p, cast_params(context.binding, binding(), env)), tokens: tokens, string: plan(tokens, context, sql.id, module), inspect: plan_inspect(data, sql.id)} + {string, inspect} = plan(tokens, Map.merge(context, %{sql_lock: sql_lock, module: module}), sql.id, stack) + %{sql | params: :lists.flatten(p, cast_params(context.binding, binding(), env)), tokens: tokens, string: string, inspect: inspect} end end end @@ -147,38 +165,80 @@ defmodule SQL do end @doc false - def plan(tokens, context, id, module) do - key = {module, id, :plan} + def plan(tokens, context, id, stack) do + key = {context.module, id, :plan} case :persistent_term.get(key, nil) do nil -> - {:ok, _context, tokens} = SQL.Parser.parse(tokens, context) - string = IO.iodata_to_binary(module.token_to_string(tokens)) - :persistent_term.put(key, string) - string + {:ok, context, tokens} = SQL.Parser.parse(tokens, context) + format = format(tokens, context, stack) + :persistent_term.put(key, format) + format - string -> - string + format -> + format end end @doc false - def plan_inspect(data, id) do - key = {id, :inspect} - case :persistent_term.get(key, nil) do - nil when is_binary(data) -> - :persistent_term.put(key, data) - data - nil -> - inspect = data - |> Enum.map(fn - ast when is_struct(ast) -> ast.inspect - x -> x - end) - |> IO.iodata_to_binary() - :persistent_term.put(key, inspect) - inspect - inspect -> - inspect + def build_lock() do + case elem(Code.eval_file("sql.lock", File.cwd!()), 0) do + %{tables: tables, columns: columns} = data -> + %{data | + tables: Enum.map(tables, fn %{table_name: table_name} = table -> %{table | table_name: to_match(table_name)} end), + columns: Enum.map(columns, fn %{table_name: table_name, column_name: column_name} = column -> %{column | table_name: to_match(table_name), column_name: to_match(column_name)} end) + } + data -> data end end + + @doc false + def to_match(value), do: {value, atom(value), function(value)} + + @doc false + def function(value) do + {:fn, [], [head(value),{:->, [], [[{:_, [], Elixir}], false]}]} + |> Code.eval_quoted() + |> elem(0) + end + + @doc false + def atom(value), do: String.to_atom(String.downcase(value)) + + @doc false + def match(value), do: Enum.reduce(1..byte_size(value), [], fn n, acc -> [acc | [{:"b#{n}", [], Elixir}]] end) + + @doc false + def head(value), do: {:->, [], [[{:when, [],[match(value),guard(value)]}], true]} + + @doc false + def guard(value, acc \\ []) do + {value, _n} = for <>, reduce: {acc, 1} do + {[], n} -> {__guard__(k, n), n+1} + {acc, n} -> {{:and, [context: Elixir, imports: [{2, Kernel}]], [acc,__guard__(k, n)]}, n+1} + end + value + end + + @doc false + def __guard__(k, n) do + {:in, [context: Elixir, imports: [{2, Kernel}]],[{:"b#{n}", [], Elixir},{:sigil_c, [delimiter: "\"", context: Elixir, imports: [{2, Kernel}]],[{:<<>>, [], ["#{<>}#{String.upcase(<>)}"]}, []]}]} + end + + @doc false + def format_error(errors), do: Enum.group_by(errors, &elem(&1, 2)) |> Enum.reduce([], fn + {k, v}, acc -> [acc | ["the relation ", :red, k, :reset, " is mentioned #{length(v)} times but does not exist", ?\n]] + end) + + @doc false + def format(tokens, %{errors: [], module: module} = context, _stack) do + {IO.iodata_to_binary(module.token_to_string(tokens)), ~s[~SQL"""\n#{IO.iodata_to_binary(IO.ANSI.format(module.to_iodata(tokens, Map.merge(%{format: true}, context), 0, []), false))}"""]} + end + + @doc false + def format(tokens, %{errors: errors, module: module} = context, stack) do + iodata = module.to_iodata(tokens, Map.merge(%{format: true}, context), 0, []) + {:current_stacktrace, [_|t]} = Process.info(self(), :current_stacktrace) + IO.warn(IO.ANSI.format([?\n, format_error(errors), iodata]), [stack|t]) + {IO.iodata_to_binary(module.token_to_string(tokens)), ~s[~SQL"""\n#{IO.iodata_to_binary(IO.ANSI.format(iodata, false))}"""]} + end end diff --git a/lib/token.ex b/lib/token.ex index a2e545c..486c2ef 100644 --- a/lib/token.ex +++ b/lib/token.ex @@ -4,18 +4,37 @@ defmodule SQL.Token do @moduledoc false + @type token :: {atom, keyword, list} + @type tokens :: [{atom, keyword, list}] + @doc """ Returns a SQL string for a given token. """ @doc since: "0.2.0" - @callback token_to_string(token :: {atom, keyword, list}) :: String.t() + @doc deprecated: "Use SQL.Token.to_iodata/3 instead" + @callback token_to_string(tokens | token) :: String.t() + + @doc """ + Returns a SQL string for a given token. + """ + @doc since: "0.3.0" + @callback to_iodata(token :: {atom(), keyword(), list()}, context :: map(), indent :: non_neg_integer()) :: iodata() defmacro __using__(opts) do quote bind_quoted: [opts: opts] do @doc false @behaviour SQL.Token def token_to_string(token), do: SQL.Adapters.ANSI.token_to_string(token, __MODULE__) - defoverridable token_to_string: 1 + def to_iodata(token, context, indent), do: SQL.Adapters.ANSI.module.to_iodata(token, context, indent) + + def to_iodata([], _context, _indent, acc), do: acc + def to_iodata([[]|tokens], context, indent, acc), do: to_iodata(tokens, context, indent, acc) + def to_iodata([token|tokens], context, indent, acc), do: to_iodata(tokens, context, indent, [acc|context.module.to_iodata(token, context, indent)]) + + def indention(indent, acc \\ []) + def indention(0, acc), do: acc + def indention(indent, acc), do: indention(indent-1, [?\s, ?\s|acc]) + defoverridable token_to_string: 1, to_iodata: 3 end end end diff --git a/mix.exs b/mix.exs index 229a6d6..94624ff 100644 --- a/mix.exs +++ b/mix.exs @@ -44,6 +44,8 @@ defmodule SQL.MixProject do {:ecto_sql, "~> 3.12", only: [:dev, :test]}, {:ex_doc, "~> 0.37", only: :dev}, {:postgrex, ">= 0.0.0", only: [:dev, :test]}, + {:tds, ">= 0.0.0", only: [:dev, :test]}, + {:myxql, ">= 0.0.0", only: [:dev, :test]}, {:yamerl, ">= 0.0.0", only: [:dev, :test]}, {:unicode_set, "~> 1.0"} ] diff --git a/mix.lock b/mix.lock index 22123c7..18b8eab 100644 --- a/mix.lock +++ b/mix.lock @@ -10,9 +10,11 @@ "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, + "myxql": {:hex, :myxql, "0.8.0", "60c60e87c7320d2f5759416aa1758c8e7534efbae07b192861977f8455e35acd", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:geo, "~> 3.4 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "1ec0ceb26fb3cd0f8756519cf4f0e4f9348177a020705223bdf4742a2c44d774"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "postgrex": {:hex, :postgrex, "0.20.0", "363ed03ab4757f6bc47942eff7720640795eb557e1935951c1626f0d303a3aed", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "d36ef8b36f323d29505314f704e21a1a038e2dc387c6409ee0cd24144e187c0f"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, + "tds": {:hex, :tds, "2.3.5", "fedfb96d53206f01eac62ead859e47e1541a62e1553e9eb7a8801c7dca59eae8", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "52e350f5dd5584bbcff9859e331be144d290b41bd4c749b936014a17660662f2"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, "unicode": {:hex, :unicode, "1.20.0", "10189cfe98b03ebb8be6efd00df0936c1c94d75bfbd62cba2bdf958fef3ee4a7", [:mix], [], "hexpm", "fa581cf80b3b1b7f42e4d24a69109dfac465cec27a62c661306c81f4ab35894c"}, "unicode_set": {:hex, :unicode_set, "1.5.0", "f2dcc40b1e8daf1a04433c705d9a8fb8ccdfc8fd5763a92d414a3e0775414cfb", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:unicode, "~> 1.13", [hex: :unicode, repo: "hexpm", optional: false]}], "hexpm", "6c7f200e52fb90434d6b783eaa4e0ea303cfc4844ea25b2fc1ba3eb8a6901b11"}, diff --git a/sql.lock b/sql.lock new file mode 100644 index 0000000..854c57b --- /dev/null +++ b/sql.lock @@ -0,0 +1 @@ +%{columns: [], tables: []} diff --git a/test/formatter_test.exs b/test/formatter_test.exs index 525aba1..f2b6f43 100644 --- a/test/formatter_test.exs +++ b/test/formatter_test.exs @@ -9,6 +9,6 @@ defmodule SQL.FormatterTest do end test "format/2 preserve interpolation" do - assert "with recursive temp(n, fact) as (select 0, 1 union all select n + {{one}}, (n + {{one}}) * fact from temp where n < 9)" == SQL.MixFormatter.format("with recursive temp(n, fact) as (select 0, 1 union all select n + {{one}}, (n + {{one}}) * fact from temp where n < 9)", []) + assert "with recursive temp(n, fact) as (\n select\n 0, \n 1\n union all\n select\n n + {{one}}, \n (n + {{one}}) * fact\n from\n temp\n where\n n < 9\n)" == SQL.MixFormatter.format("with recursive temp(n, fact) as (select 0, 1 union all select n + {{one}}, (n + {{one}}) * fact from temp where n < 9)", []) end end diff --git a/test/parser_test.exs b/test/parser_test.exs new file mode 100644 index 0000000..5b17321 --- /dev/null +++ b/test/parser_test.exs @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: 2025 DBVisor + +defmodule SQL.ParserTest do + use ExUnit.Case, async: true + + @query """ + select * + from users, users as u, users, public.users, [public].[users], "public"."users" + inner join users + join users + left outer join users + left join users + natural join users + full join users + cross join users + join users u + join users on id = id + join users u on id = id + join users on (id = id) + join (select * from users) on (id = id) + join (select * from users) u on (id = id) + """ + + describe "error" do + test "missing table with sql.lock and with tables in it" do + {:ok, context, tokens} = SQL.Lexer.lex(@query) + {:ok, %{errors: errors}, _tokens} = SQL.Parser.parse(tokens, SQLTest.Helpers.set_sql_lock(context)) + assert length(errors) == 20 + end + + test "missing table with sql.lock and without tables in it" do + {:ok, context, tokens} = SQL.Lexer.lex(@query) + context = Map.put(context, :sql_lock, %{tables: []}) + {:ok, %{errors: []}, _tokens} = SQL.Parser.parse(tokens, context) + end + + test "missing table without sql.lock" do + {:ok, context, tokens} = SQL.Lexer.lex(@query) + context = Map.put(context, :sql_lock, nil) + {:ok, %{errors: []}, _tokens} = SQL.Parser.parse(tokens, context) + end + end +end diff --git a/test/sql_test.exs b/test/sql_test.exs index 8a4f14b..71fb558 100644 --- a/test/sql_test.exs +++ b/test/sql_test.exs @@ -3,6 +3,8 @@ defmodule SQLTest do use ExUnit.Case, async: true + import ExUnit.CaptureIO + import SQLTest.Helpers import SQL def from(var \\ "users") do @@ -33,7 +35,7 @@ defmodule SQLTest do end test "inspect/1" do - assert ~s(~SQL"""\nselect +1000\n""") == inspect(~SQL[select +1000]) + assert ~s(~SQL"""\nselect\n +1000\n""") == inspect(~SQL[select +1000]) end test "to_sql/1" do @@ -101,6 +103,10 @@ defmodule SQLTest do SQL.parse("select id from users join orgs on 'id") end end + + test "missing relation" do + assert capture_io(:stderr, fn -> SQL.parse("select id from users", set_sql_lock()) end) =~ "is mentioned 1 times but does not exist" + end end describe "functions" do diff --git a/test/test_helper.exs b/test/test_helper.exs index 431c62d..3d3d8be 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -4,4 +4,9 @@ defmodule SQL.Repo do use Ecto.Repo, otp_app: :sql, adapter: Ecto.Adapters.Postgres end +defmodule SQLTest.Helpers do + def table_name([[[[[], b1], b2], b3],b4]) when b1 in ~c"tT" and b2 in ~c"eE" and b3 in ~c"sS" and b4 in ~c"tT", do: true + def table_name(_), do: false + def set_sql_lock(context \\ %{}), do: Map.merge(context, %{sql_lock: %{tables: [%{table_name: {"test", :test, &table_name/1}}]}, module: SQL.Adapters.ANSI}) +end ExUnit.start()