-
Notifications
You must be signed in to change notification settings - Fork 25.8k
Only negate index expression on all indices with preceding wildcard #20898
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
Conversation
There is currently a very confusing behavior in Elasticsearch for the following: Given the indices: `[test1, test2, -foo1, -foo2]` ``` DELETE /-foo* ``` Will cause the `test1` and `test2` indices to be deleted, when what is usually intended is to delete the `-foo1` and `-foo2` indices. Previously we added a change in elastic#20033 to disallow creating indices starting with `-` or `+`, which will help with this situation. However, users may have existing indices starting with these characters. This changes the negation to only take effect in a wildcard (`*`) has been seen somewhere in the expression, so in order to delete `-foo1` and `-foo2` the following now works: ``` DELETE /-foo* ``` As well as: ``` DELETE /-foo1,-foo2 ``` so in order to actually delete everything except for the "foo" indices (ie, `test1` and `test2`) a user would now issue: ``` DELETE /*,--foo* ``` Relates to elastic#19800
|
Wheh. Pure negatives getting an implicit |
|
So, yeah, I think this is a good idea. Though I expect it needs docs updates. |
|
I wonder if it'd be more clear to just reject pure negative index patterns entirely..... |
I tend to agree, it is confusing to accept |
I can open up a followup after this for rejecting these in the master branch only, once we get this one hammered out. |
javanna
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a couple of comments, I think we may want to update api-conventions.asciidoc also, and look if we have this negation anywhere in our docs, not sure.
| throw infe(expression); | ||
| } | ||
|
|
||
| if (expression.contains("*")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens with +test1, +test2, +test3,-test2 ? it looks silly but should be supported and resolve to test1 and test3 only. I think not only a wildcard expression can be before a negation, but there has to be something, anything that is not a negation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point I wonder if the order should still matter as it used to. Maybe negations should just subtract from the rest of the indices mentioned in the expression, with the requirement that an expression cannot be a negation only, otherwise we interpret it as an explicit index name that contains -. Should -test1,test* resolve to the same indices as test*,-test1? What other edge cases am I missing here? I also wonder why we support + as it is implicit anyway when missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens with
+test1, +test2, +test3,-test2
That would resolve to: ["test1", "test2", "test3", "-test2"], assuming a -test2 index exists, which I think is the correct behavior?
If -test2 doesn't exist then it won't be negated and in that case I'm not sure what we want to do, do you think we should support this (adding and then removing an index without wildcards)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+as it is implicit anyway when missing
+1 to remove + as an operator in a followup for 6.0-only, it's just confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would resolve to: ["test1", "test2", "test3", "-test2"], assuming a -test2 index exists, which I think is the correct behavior?
I see, yea that's ok, just different compared to before (we would previously add and remove test2, but there was no way to refer to -test2 if existing I believe), but correct. Do we have a test for this too?
I think documenting all this under the api conventions page would clear things up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about the ordering thing that I mentioned before? Should -test1,test* resolve to the same indices as test*,-test1? It doesn't now right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should
-test1,test*resolve to the same indices astest*,-test1? It doesn't now right?
It doesn't right now, I think it would depend on if a -test1 index existed.
I don't think it should though, since the intended behavior would be different regardless if you swapped the ordering of negations? What do you think?
Maybe instead we should start with a list of indices and work backwards towards what we expect for certain combinations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid we need to rely on the order if we want to be able to distinguish between negations (applied when a wildcard expression appears before the negation) and referring to indices that start with -. We will be able to get rid of it in 6.0 only when we will be sure such indices are not around anymore. I opened #20962.
Can we also have a test where the wildcard expression is not the first expression but still before the negation? e.g. test1,test2,index*,-index1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also -test1,*test2*,-test20 or something along those lines? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I've added both of those tests :)
sounds great thanks |
| boolean wildcardSeen = false; | ||
| for (int i = 0; i < expressions.size(); i++) { | ||
| String expression = expressions.get(i); | ||
| if (aliasOrIndexExists(metaData, expression)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you understand this if block? I suspect it made sense before your change, to make it possible to refer to existing indices or aliases that started with - rather than treating the name as a negation. That said, I can't quite follow why it makes sense in some cases for result to be null. This was already there, not your doing but I wonder if it's related and may be cleaned up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why it doesn't initialize the result set like the other null checks do, but I do think all of this code should be cleaned up after this (I hesitate to touch more code as this is supposed to be backported all the way back to 2.4)
| throw infe(expression); | ||
| } | ||
|
|
||
| if (expression.contains("*")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we use the existing Regex.isSimpleMatchPattern instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly, pushed something that does that
| } | ||
|
|
||
| if (expression.contains("*")) { | ||
| wildcardSeen = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should set this to true only if options.expandWildcardsOpen || options.expandWildcardsClosed . Otherwise wildcard expressions don't get expanded...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, I've changed the if to check these
|
|
||
| if (expression.contains("*")) { | ||
| if (Regex.isSimpleMatchPattern(expression) && | ||
| (options.expandWildcardsOpen() || options.expandWildcardsClosed())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add some tests around checking the options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually reverted the change to add the check, because if wildcards are both disabled then this check is already handled at a higher level, in resolve instead of innerResolve:
elasticsearch/core/src/main/java/org/elasticsearch/cluster/metadata/IndexNameExpressionResolver.java
Lines 559 to 561 in e57720e
| if (options.expandWildcardsClosed() == false && options.expandWildcardsOpen() == false) { | |
| return expressions; | |
| } |
…20898) * Only negate index expression on all indices with preceding wildcard There is currently a very confusing behavior in Elasticsearch for the following: Given the indices: `[test1, test2, -foo1, -foo2]` ``` DELETE /-foo* ``` Will cause the `test1` and `test2` indices to be deleted, when what is usually intended is to delete the `-foo1` and `-foo2` indices. Previously we added a change in #20033 to disallow creating indices starting with `-` or `+`, which will help with this situation. However, users may have existing indices starting with these characters. This changes the negation to only take effect in a wildcard (`*`) has been seen somewhere in the expression, so in order to delete `-foo1` and `-foo2` the following now works: ``` DELETE /-foo* ``` As well as: ``` DELETE /-foo1,-foo2 ``` so in order to actually delete everything except for the "foo" indices (ie, `test1` and `test2`) a user would now issue: ``` DELETE /*,--foo* ``` Relates to #19800
…20898) * Only negate index expression on all indices with preceding wildcard There is currently a very confusing behavior in Elasticsearch for the following: Given the indices: `[test1, test2, -foo1, -foo2]` ``` DELETE /-foo* ``` Will cause the `test1` and `test2` indices to be deleted, when what is usually intended is to delete the `-foo1` and `-foo2` indices. Previously we added a change in #20033 to disallow creating indices starting with `-` or `+`, which will help with this situation. However, users may have existing indices starting with these characters. This changes the negation to only take effect in a wildcard (`*`) has been seen somewhere in the expression, so in order to delete `-foo1` and `-foo2` the following now works: ``` DELETE /-foo* ``` As well as: ``` DELETE /-foo1,-foo2 ``` so in order to actually delete everything except for the "foo" indices (ie, `test1` and `test2`) a user would now issue: ``` DELETE /*,--foo* ``` Relates to #19800
…lastic#20898) * Only negate index expression on all indices with preceding wildcard There is currently a very confusing behavior in Elasticsearch for the following: Given the indices: `[test1, test2, -foo1, -foo2]` ``` DELETE /-foo* ``` Will cause the `test1` and `test2` indices to be deleted, when what is usually intended is to delete the `-foo1` and `-foo2` indices. Previously we added a change in elastic#20033 to disallow creating indices starting with `-` or `+`, which will help with this situation. However, users may have existing indices starting with these characters. This changes the negation to only take effect in a wildcard (`*`) has been seen somewhere in the expression, so in order to delete `-foo1` and `-foo2` the following now works: ``` DELETE /-foo* ``` As well as: ``` DELETE /-foo1,-foo2 ``` so in order to actually delete everything except for the "foo" indices (ie, `test1` and `test2`) a user would now issue: ``` DELETE /*,--foo* ``` Relates to elastic#19800
There is currently a very confusing behavior in Elasticsearch for the
following:
Given the indices:
[test1, test2, -foo1, -foo2]Will cause the
test1andtest2indices to be deleted, when what isusually intended is to delete the
-foo1and-foo2indices.Previously we added a change in #20033 to disallow creating indices
starting with
-or+, which will help with this situation. However,users may have existing indices starting with these characters.
This changes the negation to only take effect in a wildcard (
*) hasbeen seen somewhere in the expression, so in order to delete
-foo1and-foo2the following now works:As well as:
so in order to actually delete everything except for the "foo" indices
(ie,
test1andtest2) a user would now issue:Relates to #19800