From 81b1754d796146763528ba3258f0625094343359 Mon Sep 17 00:00:00 2001 From: Irwin <153746342+irwin-chequer@users.noreply.github.com> Date: Fri, 14 Jun 2024 19:12:03 +0900 Subject: [PATCH] =?UTF-8?q?[QP-9265]=20Insert=20Set=20=EA=B5=AC=EB=AC=B8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20identifier=20=ED=8C=8C=EC=8B=B1=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20(#92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Changes ### AS-IS MySQL, MariaDB 에서 지원되는 `INSERT .... SET` 쿼리의 경우 identifier 가 `{테이블명}.{컬럼명}` 형식으로 들어오는데, 기존 QSI 에서는 이 경우 컬럼명이 아니라 테이블명을 파싱하기 때문에 에러를 일으킵니다. 또한, default 값이 지정돼있으나 not null 제약조건이 있는 경우 insert 를 통해 null 을 대입하면 default 값이 할당되나, 기존 코드는 null 을 대입하는 것으로 보고 not null 에러를 일으킵니다. ### TO-BE identifier 를 적절히 파싱하고, default 있는 경우에 null 대입하면 적절히 default 대입하도록 수정합니다. 또한, 테스트 케이스 실행 결과를 검증하는 부분을 적절히 수정합니다. ## Note 이 이슈로 인한 NotNullConstraints 에러는 테이블을 가져오면서 각 컬럼의 IsNullable 정보를 적절히 가져오는 구현을 했던 경우에만 발생하는 에러이므로, IsNullable 정보를 적절히 가져오는 구현을 하지 않았던 경우에는 에러가 발생하지 않았습니다. --- ..., -, -_parameters=System.Object[].verified.txt | 14 +++++++------- ...me = -_parameters=System.Object[].verified.txt | 14 +++++++------- ... SELECT 1, 'MORRIS', 'BABO', null.verified.txt | 14 +++++++------- ...MORRIS', actor.last_name = 'BABO'.verified.txt | 14 +++++++------- Qsi/Analyzers/Action/QsiActionAnalyzer.cs | 15 ++++++++++----- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SELECT -, -, -, -_parameters=System.Object[].verified.txt b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SELECT -, -, -, -_parameters=System.Object[].verified.txt index 496901c2..9a3f8423 100644 --- a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SELECT -, -, -, -_parameters=System.Object[].verified.txt +++ b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SELECT -, -, -, -_parameters=System.Object[].verified.txt @@ -1,8 +1,8 @@  -+-------------------------------------------------+ -| qsi_unit_tests.actor - INSERT | -+----------+------------+-----------+-------------+ -| actor_id | first_name | last_name | last_update | -+----------+------------+-----------+-------------+ -| 1 | MORRIS | BABO | null | -+-------------------------------------------------+ ++-------------------------------------------------------+ +| qsi_unit_tests.actor - INSERT | ++----------+------------+-----------+-------------------+ +| actor_id | first_name | last_name | last_update | ++----------+------------+-----------+-------------------+ +| 1 | MORRIS | BABO | CURRENT_TIMESTAMP | ++-------------------------------------------------------+ diff --git a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SET actor.first_name = -, actor.last_name = -_parameters=System.Object[].verified.txt b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SET actor.first_name = -, actor.last_name = -_parameters=System.Object[].verified.txt index b55d6532..8df1c8c5 100644 --- a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SET actor.first_name = -, actor.last_name = -_parameters=System.Object[].verified.txt +++ b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_BindParam_sql=INSERT INTO actor SET actor.first_name = -, actor.last_name = -_parameters=System.Object[].verified.txt @@ -1,8 +1,8 @@  -+-------------------------------------------------+ -| qsi_unit_tests.actor - INSERT | -+----------+------------+-----------+-------------+ -| actor_id | first_name | last_name | last_update | -+----------+------------+-----------+-------------+ -| default | MORRIS | BABO | default | -+-------------------------------------------------+ ++-------------------------------------------------------------+ +| qsi_unit_tests.actor - INSERT | ++----------------+------------+-----------+-------------------+ +| actor_id | first_name | last_name | last_update | ++----------------+------------+-----------+-------------------+ +| AUTO_INCREMENT | MORRIS | BABO | CURRENT_TIMESTAMP | ++-------------------------------------------------------------+ diff --git a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SELECT 1, 'MORRIS', 'BABO', null.verified.txt b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SELECT 1, 'MORRIS', 'BABO', null.verified.txt index 496901c2..9a3f8423 100644 --- a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SELECT 1, 'MORRIS', 'BABO', null.verified.txt +++ b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SELECT 1, 'MORRIS', 'BABO', null.verified.txt @@ -1,8 +1,8 @@  -+-------------------------------------------------+ -| qsi_unit_tests.actor - INSERT | -+----------+------------+-----------+-------------+ -| actor_id | first_name | last_name | last_update | -+----------+------------+-----------+-------------+ -| 1 | MORRIS | BABO | null | -+-------------------------------------------------+ ++-------------------------------------------------------+ +| qsi_unit_tests.actor - INSERT | ++----------+------------+-----------+-------------------+ +| actor_id | first_name | last_name | last_update | ++----------+------------+-----------+-------------------+ +| 1 | MORRIS | BABO | CURRENT_TIMESTAMP | ++-------------------------------------------------------+ diff --git a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SET actor.first_name = 'MORRIS', actor.last_name = 'BABO'.verified.txt b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SET actor.first_name = 'MORRIS', actor.last_name = 'BABO'.verified.txt index b55d6532..8df1c8c5 100644 --- a/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SET actor.first_name = 'MORRIS', actor.last_name = 'BABO'.verified.txt +++ b/Qsi.Tests/Vendor/MySql/verified/MySqlTest.Test_Print_sql=INSERT INTO actor SET actor.first_name = 'MORRIS', actor.last_name = 'BABO'.verified.txt @@ -1,8 +1,8 @@  -+-------------------------------------------------+ -| qsi_unit_tests.actor - INSERT | -+----------+------------+-----------+-------------+ -| actor_id | first_name | last_name | last_update | -+----------+------------+-----------+-------------+ -| default | MORRIS | BABO | default | -+-------------------------------------------------+ ++-------------------------------------------------------------+ +| qsi_unit_tests.actor - INSERT | ++----------------+------------+-----------+-------------------+ +| actor_id | first_name | last_name | last_update | ++----------------+------------+-----------+-------------------+ +| AUTO_INCREMENT | MORRIS | BABO | CURRENT_TIMESTAMP | ++-------------------------------------------------------------+ diff --git a/Qsi/Analyzers/Action/QsiActionAnalyzer.cs b/Qsi/Analyzers/Action/QsiActionAnalyzer.cs index 19824440..4ee2bd29 100644 --- a/Qsi/Analyzers/Action/QsiActionAnalyzer.cs +++ b/Qsi/Analyzers/Action/QsiActionAnalyzer.cs @@ -629,7 +629,7 @@ protected virtual SetColumnTarget ResolveSetColumnTarget( protected virtual QsiTableColumn ResolveNotNullableColumnWithInvalidDefault(IEnumerable columns, IEnumerable columnTargets) { - HashSet targetNames = columnTargets.Select(ct => ct.DeclaredName.SubIdentifier(0).ToString()).ToHashSet(); + HashSet targetNames = columnTargets.Select(ct => ct.DeclaredName.SubIdentifier(^1).ToString()).ToHashSet(); return columns .FirstOrDefault(x => !targetNames.Contains(x.Name.Value) && !x.IsNullable && x.Default is null); @@ -685,7 +685,10 @@ private async ValueTask ProcessQueryValues(TableDataInsertContext context, IQsiT foreach (var row in dataTable.Rows) { - PopulateInsertRow(context, pivot => row.Items[pivot.SourceOrder]); + PopulateInsertRow(context, pivot => + { + return row.Items[pivot.SourceOrder]; + }); } var tableAnalyzer = context.Engine.GetAnalyzer(); @@ -801,9 +804,11 @@ private void PopulateInsertRow(TableDataInsertContext context, DataValueSelector { ref var item = ref targetRow.Items[pivot.DestinationOrder]; - item = pivot.SourceColumn is not null - ? valueSelector(pivot) - : ResolveDefaultColumnValue(pivot); + if (pivot.SourceColumn is not null) + item = valueSelector(pivot); + + if (item?.Value is null) + item = ResolveDefaultColumnValue(pivot); if (item.Value is null && target.Table.Columns[pivot.DestinationOrder].IsNullable == false) throw new QsiException(QsiError.NotNullConstraints, pivot.DestinationColumn.Name.Value);