fix(utils_sql): improve insert sql regular expression

This commit is contained in:
JimMoen 2024-06-05 18:09:24 +08:00
parent ae0379f974
commit 627b8c45d2
No known key found for this signature in database
1 changed files with 20 additions and 11 deletions

View File

@ -54,17 +54,26 @@ get_statement_type(Query) ->
-spec parse_insert(iodata()) -> -spec parse_insert(iodata()) ->
{ok, {_Statement :: binary(), _Rows :: binary()}} | {error, not_insert_sql}. {ok, {_Statement :: binary(), _Rows :: binary()}} | {error, not_insert_sql}.
parse_insert(SQL) -> parse_insert(SQL) ->
case re:split(SQL, "((?i)values)", [{return, binary}]) of Pattern = <<
[Part1, _, Part3] -> %% case-insensitive
case string:trim(Part1, leading) of "(?i)^\\s*",
<<"insert", _/binary>> = InsertSQL -> %% Group-1: insert into, table name and columns (when existed).
{ok, {InsertSQL, Part3}}; %% All space characters suffixed to <TABLE_NAME> will be kept
<<"INSERT", _/binary>> = InsertSQL -> %% `INSERT INTO <TABLE_NAME> [(<COLUMN>, ..)]`
{ok, {InsertSQL, Part3}}; "(insert\\s+into\\s+[^\\s\\(\\)]+\\s*(?:\\([^\\)]*\\))?)",
_ -> %% Keyword: `VALUES`
{error, not_insert_sql} "\\s*values\\s*",
end; %% Group-2: literals value(s) or placeholder(s) with round brackets.
_ -> %% And the sub-pattern in brackets does not do any capturing
%% `([<VALUE> | <PLACEHOLDER>], ..])`
"(\\((?:[^()]++|(?2))*\\))",
"\\s*$"
>>,
case re:run(SQL, Pattern, [{capture, all_but_first, binary}]) of
{match, [InsertInto, ValuesTemplate]} ->
{ok, {InsertInto, ValuesTemplate}};
nomatch ->
{error, not_insert_sql} {error, not_insert_sql}
end. end.