-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
usePreparedStatement attribute in loadData element has no effect #1098
usePreparedStatement attribute in loadData element has no effect #1098
Conversation
…ged its weight in later decision
@jdhmoreno! That's a fast turn-around, you're awesome! Now the canned stuff: Here’s what happens next: A member of the Liquibase team will take a look at your contribution and may suggest We’ll let you know when it’s ready to move to the next step or if any changes are needed. |
Hey @jdhmoreno, I'm trying to size this merge request for the internal Liquibase team, and I think I can size it smaller (and therefore get the change in faster) if we have unit tests. I would write it myself but I'm still a newbie myself. Here is our documentation and example for writing unit test. For this PR that means we would create a matching unit test file here: Up for this? :) Let me know. That would make it a RiskLow in my mind, otherwise I would peg it with RiskMedium, which would have to wait till at least 1-2 more sprints. Thanks, Ronak |
hi @ro-rah yeah, no prob, need to scrape some time to do them. sadly I've to the following error (attached) when running the tests (haven't added any tests yet, just got the error running looks strange, though. I could successfully run the tests early this week on a fork of the 3.8.9 tag. Some context jdk/mvn --version: openjdk 11.0.6 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1, mixed mode, sharing) Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: <BLABLA ;-)>
Java version: 11.0.6, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "4.4.0-18362-microsoft", arch: "amd64", family: "unix" Got the errors attached, any ideas? 2020-04-17T18-13-22_867.dumpstream.txt |
Hey @jdhmoreno , Okay, bear with me here, looks like jococo is choking, maybe it does not like OpenJDK 11? Although that is pretty old issue...and it looks like they added support for Java 11 & 12, just not sure if it is for OpenJDK. I'm bringing this issue up internally too. Thanks, Ronak |
Hey @ro-rah, Something's fishy with openjdk. it cannot compile on any of the ones I've tried (from version 9 to 14) In any case, with an Oracle JDK 8 did work, so I kept working on the unit tests. I've added a unit test that checks what's happening when the flag 'usePreparedStatements' is set to FALSE (defaults to TRUE) but I'm unsure about what's the difference between a new MSSQLDatabase object and MockDatabase. The behaviour to test has to do with the database's ability to 'supportsBatchUpdates', which in both cases is always 'false' --> due to the creation of an 'offline' connection, whereas in a real MSSqlserver instance, that will be 'true'. I guess we should somehow mock it? In the other hand, all the regression tests pass successfully. |
Codecov Report
@@ Coverage Diff @@
## master #1098 +/- ##
=========================================
Coverage 47.71% 47.72%
- Complexity 7477 7479 +2
=========================================
Files 757 757
Lines 36278 36278
Branches 6624 6624
=========================================
+ Hits 17311 17312 +1
+ Misses 16660 16659 -1
Partials 2307 2307
Continue to review full report at Codecov.
|
This is great! Let me see if we can take it as is. I wanted to point out that our Travis build results are viewable down below, and you can see our output of running the tests. Just info for any future PRs you may submit. Thanks for sticking with it and getting the test to work with Open JDK 8, that saves a ton of time for us isolating the issue, so I also thank you on that account. I'll keep ya posted! |
closes #1091 |
labeled this RiskLow as this is currently broken, this PR aims to fix. |
➤ Erzsebet Carmean commented: @jdhmoreno, wow! Thank you for the excellent repro steps! I'm in QA and love well-documented bugs! |
Documented on issue
#1091
Copied issue description here
Environment
Liquibase Version: 3.8.9
Liquibase Integration & Version: maven liquibase plugin, also version 3.8.9; maven version 3.6.3
Liquibase Extension(s) & Version:
Database Vendor & Version: SQLServer 2012
Operating System Type & Version: Ubuntu running Docker 19.0.3
Description
Regardless of whether the attribute 'usePreparedStatements' is set to 'true' or 'false' in 'loadData' elements, Liquibase always uses prepared statements (so it behaves as if it were harcoded to 'true')
This is the cause why when we try to load a CSV file where a 'DATE' column is set to 'NULL' we get the following error:
{NOFORMAT}
Error setting up or running Liquibase:
[ERROR] Migration failed for change set liquibase/xxx:
[ERROR] Reason: liquibase.exception.DatabaseException: java.sql.BatchUpdateException: Implicit conversion from data type varbinary to datetime2 is not allowed. Use the CONVERT function to run this query.
{NOFORMAT}
This was already reported in https://liquibase.jira.com/browse/CORE-3399
As a workaround to overcome this problem, I've tried to set the 'usePreparedStatements' (in order to force the creation of liquibase's
InsertStatements
) to 'false' but it has no effect.It all seems to be in Liquibase's 'LoadDataChange' class, in the condition that starts in line 464 from the liquibase codebase, GIT tag 3.8.9:
The value of the flag 'needsPreparedStatement' is not taken into account in that condition, because:
as stated in the JDBC driver) andSo 'needsPreparedStatement' will have no effect.
Steps To Reproduce
POM.xml
changelog-master.xml
under src/main/resourcestest_date.csv
under src/main/resources{NOFORMAT}
"ID","DATE_COLUMN"
"1","NULL"
"2","NULL"
"3","NULL"
{NOFORMAT}
maven
command{NOFORMAT}
[ERROR] Failed to execute goal org.liquibase:liquibase-maven-plugin:3.8.9:update (default-cli) on project test.database.problem:
[ERROR] Error setting up or running Liquibase:
[ERROR] Migration failed for change set liquibase/changelog-master.xml::testProblemSqlServer::jdhmoreno:
[ERROR] Reason: liquibase.exception.DatabaseException: java.sql.BatchUpdateException: Implicit conversion from data type varbinary to datetime2 is not allowed. Use the CONVERT function to run this query.
[ERROR] -> [Help 1]
{NOFORMAT}
Expected/Desired Behavior
The idea would be that, when
usePreparedStatements="false"
is set in the loadData element, no PreparedStatements are used.Proposed solution / idea
A solution might be to have the following condition in the class 'LoadDataChange', line 455
This way,
needsPreparedStatement
(which in turns depends on the 'usePreparedStatement' attribute) will drive the creation of PreparedStatements or InsertStatements.This should help solving the 'date' issue shown above, leaving to the developer the option of enabling them or not.
Notes
A more detailed look on why SQLServer 2012 behaves that way when a SQL NULL is sent for a DATE column can be found in the following StackOverflow thread:
https://stackoverflow.com/questions/43935316/error-inserting-null-or-empty-value-in-date-column-mapped-to-localdate-type-in-j
Liquibase Internal QA Requirements
Note to Community: The functional Liquibase tests run on our internal build system and are not visible to the broader community.
┆Issue is synchronized with this Jira Bug by Unito
┆fixVersions: Community 4.x,Liquibase 4.3.2