This querry is particularly problamatic when there are OR conditions due
to shared docs.
```sql
ANALYZE SELECT `tabAddress`.name,
`tabAddress`.city,
`tabAddress`.country
FROM `tabAddress`
join `tabDynamic Link` on (`tabDynamic Link`.parent = `tabAddress`.name AND `tabDynamic Link`.parenttype = 'Address')
WHERE
`tabDynamic Link`.link_doctype = 'Customer'
AND `tabDynamic Link`.link_name = 'CUSTOMER NAME'
AND coalesce(`tabAddress`.disabled, 0) = 0
AND (`tabAddress`.`country` like '%%'
OR `tabAddress`.`state` like '%%'
OR `tabAddress`.`name` like '%%'
OR `tabAddress`.`name` like '%%')
AND ((((coalesce(`tabAddress`.`branch`, '')=''
OR `tabAddress`.`branch` in ('something')))))
OR (`tabAddress`.name in ('SOME SHARED DOC'))
ORDER BY if(locate('', `tabAddress`.name), locate('', `tabAddress`.name), 99999),
`tabAddress`.idx DESC,
`tabAddress`.name
LIMIT 0, 20;
```
**Before:** Never terminates and reads entire table with millions of lines :LOL:
**After:** Reads ~100 rows max.
```
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: tabDynamic Link
type: index_merge
possible_keys: parent,link_doctype_link_name_index,link_name
key: link_name,link_doctype_link_name_index,parent
key_len: 563,1126,563
ref: NULL
rows: 40
r_rows: 79.00
filtered: 100.00
r_filtered: 100.00
Extra: Using union(intersect(link_name,link_doctype_link_name_index),parent); Using where; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: tabAddress
type: eq_ref
possible_keys: PRIMARY,selco_branch
key: PRIMARY
key_len: 562
ref: _900a733bdc3bb9ed.tabDynamic Link.parent
rows: 1
r_rows: 1.00
filtered: 100.00
r_filtered: 100.00
Extra: Using where
2 rows in set (0.001 sec)
```
<!--
Some key notes before you open a PR:
1. Select which branch should this PR be merged in?
2. PR name follows [convention](http://karma-runner.github.io/4.0/dev/git-commit-msg.html)
3. All tests pass locally, UI and Unit tests
4. All business logic and validations must be on the server-side
5. Update necessary Documentation
6. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes
Also, if you're new here
- Documentation Guidelines => https://github.com/frappe/erpnext/wiki/Updating-Documentation
- Contribution Guide => https://github.com/frappe/frappe/blob/develop/.github/CONTRIBUTING.md
- Pull Request Checklist => https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist
-->
> Please provide enough information so that others can review your pull request:
<!-- You can skip this if you're fixing a typo or updating existing documentation -->
> Explain the **details** for making this change. What existing problem does the pull request solve?
<!-- Example: When "Adding a function to do X", explain why it is necessary to have a way to do X. -->
> Screenshots/GIFs
<!-- Add images/recordings to better visualize the change: expected/current behviour -->
This has never worked since 2016... which can mean two things:
- No one really uses this.
- If I fix this now suddenly people will find different behaviour in
naming because `name_case` is selected in some doctypes (but never
tested)
refactor: clean up code to py39+ supported syntax
- f-strings instead of format
- latest typing support instead of pre 3.9 TitleCase
- remove UTF-8 declarations.
- many more changes
Powered by https://github.com/asottile/pyupgrade/ + manual cleanups
The license.txt file has been replaced with LICENSE for quite a while
now. INAL but it didn't seem accurate to say "hey, checkout license.txt
although there's no such file". Apart from this, there were
inconsistencies in the headers altogether...this change brings
consistency.
These modules were imported from the ERPNext codebase into Frappe.
License header was overlooked at that point. These were contributed
initially by Frappe Technologies Pvt Ltd under GPLv3 (ERPNext's license) and now
we, as Frappe Technologies Pvt Ltd converting them to MIT to comply with
Frappe's license.
* Remove six for PY2 compatability since our dependencies are not, PY2
is legacy.
* Removed usages of utils from future/past libraries since they are
deprecated. This includes 'from __future__ ...' and 'from past...'
statements.
* Removed compatibility imports for PY2, switched from six imports to
standard library imports.
* Removed utils code blocks that handle operations depending on PY2/3
versions.
* Removed 'from __future__ ...' lines from templates/code generators
* Used PY3 syntaxes in place of PY2 compatible blocks. eg: metaclass
cmp was being used from past.builtins library since it was deprecated in
PY2. It's hard to understand behaviour of their usages, so this is an
attempt to replicate behaviour with simpler logic, making this more
readable.
Also, removed usages of iteritems and string_types, compatibility
imports
- remove several unnecessary comprehensions from functions that accept a generator.
- Using `[x for x in iter]` causes a list to be built first then passed to the outer function.
- `any` and `all` can take generator instead. This makes memory usage O(1) and actually makes these functions short-circuiting. E.g. if the first condition fails then `all` will immediately return false instead of evaluating all the entries.
- `sum`, `min`, `max` => memory usage become O(1)
- `list`, `set`, `.join()` => roughly halves memory usage, as list is not required to be built.
- lastly, it's two fewer characters to read/think about.