add partial index predicate to SQLiteDialect.get_indexes() result#8806
add partial index predicate to SQLiteDialect.get_indexes() result#8806tgpfeiffer wants to merge 9 commits into
Conversation
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 0bd2750 of this pull request into gerrit so we can run tests and reviews and stuff
|
New Gerrit review created for change 0bd2750: https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200 |
|
I think I addressed your comments @CaselIT, could you take another look please? Thank you! |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision 56f16e3 of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset 56f16e3 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200 |
sqla-tester
left a comment
There was a problem hiding this comment.
Federico Caselli (CaselIT) wrote:
looks ok to me now. Thanks for updating the change
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
| "Failed to look up filter predicate of " | ||
| "partial index %s" % row[1] | ||
| ) | ||
| indexes.pop() |
There was a problem hiding this comment.
Federico Caselli (CaselIT) wrote:
this is a change compared to how the dialect works now (since it currently returns partial indexes without informations instead of ignoring them if it cannot parse them)
but since it's in an edge case that should never happen, at least when used with sqlite, I think it's fine
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
|
Sorry I am not familiar with the review process, what is the next step to get this merged, looks like I need another approval? On a related note, I would also like to see this change in the next 1.4.x bugfix release, can I do anything to help with the backporting? (I already noticed there will be a merge conflict, so it needs some manual work.) |
Mostly wait, Mike will get to this when he has time
I placed it on the 2 milestone, but it seems contained enough to be backported to 1.4. let's wait for mike opinion on this |
sqla-tester
left a comment
There was a problem hiding this comment.
mike bayer (zzzeek) wrote:
hi thanks for this! this is pretty good. I'm assuming we want this in 1.4 as 2.0 final is still some months away. Let's narrow the scope of the new logic, and there are also changes for the test suite; in the latter case, we can do that part if you dont know our test suite conventions.
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
| indexes[-1]["dialect_options"]["sqlite_where"] = text( | ||
| predicate | ||
| ) | ||
| except Exception: |
There was a problem hiding this comment.
mike bayer (zzzeek) wrote:
what Exception are we catching here? is this just if the partial_pred_re is None? Let's just assign it up front and do "if predicate_match is not None"
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
| "Failed to look up filter predicate of " | ||
| "partial index %s" % row[1] | ||
| ) | ||
| indexes.pop() |
There was a problem hiding this comment.
mike bayer (zzzeek) wrote:
this would be much safer to backport to 1.4 if we didnt actually do this indexes.pop() here, and return the same output we would have gotten previously. We can leave the new warning in place, which should be sufficient.
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
| import datetime | ||
| import json | ||
| import os | ||
| from unittest.mock import ANY |
There was a problem hiding this comment.
mike bayer (zzzeek) wrote:
for backporting this has to be "from testing.mock import ANY"
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
| ], | ||
| ) | ||
|
|
||
| def test_reflect_partial_indexes(self): |
There was a problem hiding this comment.
mike bayer (zzzeek) wrote:
use the connection fixture
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
| def test_reflect_partial_indexes(self): | ||
| with testing.db.begin() as conn: | ||
| conn.exec_driver_sql( | ||
| "create table foo_with_partial_index (x integer, y integer)" |
There was a problem hiding this comment.
mike bayer (zzzeek) wrote:
do all of these individually using a @testing.combinations() block
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200
|
(Not sure why some reviewer comments show up in github and others in gerrit only... 🤔) I addressed three of your comments (fix mock import, remove Please take another look and let me know if I should fix anything else. |
we have a mirror between the gerrit review and this PR. they should be bidrectional at the comments level.
that would replace the def test_reflect_partial_indexes(self, connection):
connection.exec_driver_sql(...)the thing we are using there is pytest fixtures. |
|
yes, it was a mistake on my part that done comment |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of CaselIT to try to get revision 44cd132 of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset 44cd132 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200 |
|
Pushed another commit making use of the |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 539dfcb of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset 539dfcb added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200 |
|
Sorry to bug you again, could you give this another round of review, please? Thank you! |
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 539dfcb of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset 539dfcb added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200 |
|
Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4200 has been merged. Congratulations! :) |
|
Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/4251 has been merged. Congratulations! :) |
Added support for reflection of expression-oriented WHERE criteria included in indexes on the SQLite dialect, in a manner similar to that of the PostgreSQL dialect. Pull request courtesy Tobias Pfeiffer. Fixes: #8804 Closes: #8806 Pull-request: #8806 Pull-request-sha: 539dfcb Change-Id: I0e34d47dbe2b9c1da6fce531363084843e5127a3 (cherry picked from commit ed39e84)
This fixes #8804 by populating the
dialect_options'ssqlite_wherefield insideSQLiteDialect.get_indexes()for an index where theindex_list()pragma indicates that it is a partial index.Description
For an index where the fifth column of the corresponding row in the
index_list()return value is true (see https://www.sqlite.org/pragma.html#pragma_index_list), we get the exact SQL used to create that index from thesqlite_mastertable and look for theWHEREkeyword, then use the string after that as thesqlite_wherepredicate.Remark: I use a simple regular expression scanning for the string
)\s+where\s+(case-insensitive) to find the predicate. As written in a comment in the code, this can easily fail if the definition of the index contains a matching string such asbut case 1 can be neglected because
get_indexes()currently does not support expression-based indexes, and case 2 can be neglected because the regex finds the first match.@CaselIT suggested in #8804 (comment) to attack expression-based indexes as well, but to be honest I am not sure what is a good way to parse the
CREATE INDEXstatement with reasonable effort in that case, so I didn't work on it. (Is there a parser somewhere in the codebase already?)I have verified that in my local environment, the case I reported in sqlalchemy/alembic#1112 (comment) works well, so the partial index is kept across migrations and this PR also fixes sqlalchemy/alembic#1112.
Checklist
This pull request is:
must include a complete example of the issue. one line code fixes without an
issue and demonstration will not be accepted.
Fixes: #<issue number>in the commit messageinclude a complete example of how the feature would look.
Fixes: #<issue number>in the commit messageHave a nice day!