-
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
Add configuration options for missing property handling #2656
Conversation
…llowing options: * LEGACY: The property placeholder will remain unexpanded. * EMPTY: The property placeholder will be replaced with an empty string. * THROW: An exception will be thrown when a placeholder with an unknown property is expanded. The exception will roughly guide the user to the offending databaseChangeLog by specifying the logical file name as well as the missing property. Also add a more meaningful error message, when a property placeholder reaches the DataTypeFactory and is misinterpreted as "embedded information", otherwise triggering an `ArrayIndexOutOfBoundsException`. LB-2586
@dwieland This is an interesting proposal. I'd love to know a bit more about the end use case/conditions you are dealing with that inspired you to create this if you wouldn't mind sharing. Thanks! |
I guess that key should be compare in method 'isDuplicate' in class ChangeLogParameter here. From below screen-shot, that these 2 ChangeLogParameters with different key. But according to logic, they are duplicated. I think the logic is in-corrected. ChangeLogParameter with different key means different parameter. |
…dwieland-LB-2586
# Conflicts: # liquibase-core/src/main/java/liquibase/datatype/DataTypeFactory.java
Thanks for the PR! In reviewing it, I took it over a bit to do a more extensive cleanup of the property handling code. We had been trying to just do some workaround patches in the property handling vs. the needed refactoring to avoid taking time to retest existing functionality. But, your switch from the regexp-based searching to scanning makes me want to make sure we do a pass through the overall functionality already so adding in the other changes I'd been holding of on. Changes I made to your original PR functionality:
That seem ok to you @dwieland ? Beyond that, it was:
Notes and test results: Things to be aware of
Things to worry about
|
…w a ChangeLogParseException
That's totally fine. Thanks for looking into it! |
- Switched unknown changelog properties to throw UnknownChangeLogParameterException
The failing functional test is unrelated to this change, so moving this along to test. Things to be aware of
Things to worry about
|
For this PR, i checked if the new option PRESERVE: Using value ${myValue} here
EMPTY: Using value here
ERROR: Exits with error
It looks like liquibase with the option Test Environment: |
@nvoxland can you please also update the docs? Thanks! |
Thanks for this enhancement. I run into its absence a few days ago and started looking for workarounds. But now i just wait till next release. Thank you a lot |
Pull Request Type
Description
Adds a new
liquibase.missingPropertyMode
setting with options ofPRESERVE
,EMPTY
, andERROR
. The default value is PRESERVE which follows the old behavior of keeping the unexpanded property in the changelog file. EMPTY will replace it with an empty value, and ERROR will exit parsing with an error.Example: if a changelog as
Using value ${myValue} here
and myValue is not defined, the result will be:Using value ${myValue} here
Using value here
This PR also does a cleanup/refactoring of the changelog property handling and the classes/methods associated with it to make the mode more maintainable and usable, as well as better avoid bugs such as #2586 and the ArrayIndexOutOfBoundsException issue listed below
ArrayIndexOutOfBoundsException Issue
Overview
The initial issue I encountered was a strange
ArrayIndexOutOfBoundsException
when running Liquibase. After some analysis I found out that it was related to #2586 - I tried to use specific varchar specifications for Oracle (VARCHAR(100 CHAR)
) while keeping compatibility with MySQL. So I specified the type like this:type: VARCHAR(100 ${sql.type.varchar.char})
, triggering the above issue as I forgot the set the property explicitly for MySQL.After investigation I found that property placeholders are left untouched if the property could not be found in the current scope. After that the
DataTypeFactory
inspects the data type and assumes some embedded information based on the occurrence of a{
. It tries to split the string in key and value and fails horribly doing so.This PR tries to address multiple aspects of the issue. It allows to configure the behavior when trying to expand a placeholder of an unknown property - keeping backwards compatibility by default. The two new modes are: "replace with empty string" and "throw meaningful exception". It also tries to give a more meaningful exception when some placeholder reaches the
DataTypeFactory
.Steps To Reproduce
Use a placeholder in
createTable.columns.column[].type
that is not backed by a property.Actual Behavior
java.lang.ArrayIndexOutOfBoundsException
is thrown, leaving the normal user clueless about what actually happened.Expected/Desired Behavior
A meaningful error is presented to the user. The behavior in the described case is configurable.
Please tell me if additional unit or integration tests are needed.
I can update the documentation if I get some hints.
Fast Track PR Acceptance Checklist: