Here the issue and a PR : https://github.com/web2py/pydal/pull/523

Please including it in the next release if it don't break anything... It
will help with backward (empty query) compatibility...

Thanks

Richard

On Tue, Feb 27, 2018 at 5:37 PM, Richard Vézina <ml.richard.vez...@gmail.com
> wrote:

> Out of _build_joins_for_select() itables_to_merge variable has only one
> table which is the one implicated in the join (in this case "auth_user")...
> But another merge_tablemaps() occurs in red below :
>
>         if join:
>             (
>                 # FIXME? ijoin_tables is never used
>                 ijoin_tables, ijoin_on, itables_to_merge, ijoin_on_tables,
>                 iimportant_tablenames, iexcluded, itablemap
>             ) = self._build_joins_for_select(tablemap, join)
>             tablemap = merge_tablemaps(tablemap, itables_to_merge)
>             tablemap = merge_tablemaps(tablemap, itablemap)
>         if left:
>             (
>                 join_tables, join_on, tables_to_merge, join_on_tables,
>                 important_tablenames, excluded, jtablemap
>             ) = self._build_joins_for_select(tablemap, left)
>             tablemap = merge_tablemaps(tablemap, tables_to_merge)
>             tablemap = merge_tablemaps(tablemap, jtablemap)
>
>
> So itables_to_merge get altered and get back to is previous state as it is
> at some point in _build_joins_for_select() (in red), but it was filtered
> in the stage in blue  :
>
> def _build_joins_for_select(self, tablenames, param):
>         if not isinstance(param, (tuple, list)):
>             param = [param]
>         tablemap = {}
>         for item in param:
>             if isinstance(item, Expression):
>                 item = item.first
>             key = item._tablename
>             if tablemap.get(key, item) is not item:
>                 raise ValueError('Name conflict in table list: %s' % key)
>             tablemap[key] = item
>         join_tables = [
>             t._tablename for t in param if not isinstance(t, Expression)
>         ]
>         join_on = [t for t in param if isinstance(t, Expression)]
>         tables_to_merge = {}
>         for t in join_on:
>             tables_to_merge = merge_tablemaps(tables_to_merge,
> self.tables(t))
>         join_on_tables = [t.first._tablename for t in join_on]
>         for t in join_on_tables:
>             print t
>             if t in tables_to_merge:
>                 print t
>                 tables_to_merge.pop(t)
>         important_tablenames = join_tables + join_on_tables + \
>             list(tables_to_merge)
>         excluded = [
>             t for t in tablenames if t not in important_tablenames
>         ]
>         return (
>             join_tables, join_on, tables_to_merge, join_on_tables,
>             important_tablenames, excluded, tablemap
>         )
>
>
> With the logic in merge_tablemaps() where things are reversed in big and
> small and big get update at the end it explains why itables_to_merge get
> modified by merge_tablemaps()
>
> def merge_tablemaps(*maplist):
>     """Merge arguments into a single dict, check for name collisions.
>     Arguments may be modified in the process."""
>     ret = maplist[0]
>     for item in maplist[1:]:
>         if len(ret) > len(item):
>             big, small = ret, item
>         else:
>             big, small = item, ret
>         # Check for name collisions
>         for key, val in small.items():
>             if big.get(key, val) is not val:
>                 raise ValueError('Name conflict in table list: %s' % key)
>         # Merge
>         big.update(small)
>         ret = big
>     return ret
>
> I don't think itables_to_merge is updated intentionally because why
> filtering it in _build_joins_for_select()...
>
> My guess is the intention wasn't to get it updated and the only purpose of
> the  tablemap with all the tables names as itablemap use lack some(s) of
> them...
>
> So deepcopy would be need it or just dict(**itables_to_merge)) while
> passing itables_to_merge to merge_tablemaps()
>
> *Should we fix that??*
>
>         if join:
>             (
>                 # FIXME? ijoin_tables is never used
>                 ijoin_tables, ijoin_on, itables_to_merge, ijoin_on_tables,
>                 iimportant_tablenames, iexcluded, itablemap
>             ) = self._build_joins_for_select(tablemap, join)
>             tablemap = merge_tablemaps(tablemap, dict(**itables_to_merge))
>             tablemap = merge_tablemaps(tablemap, itablemap)
>         if left:
>             (
>                 join_tables, join_on, tables_to_merge, join_on_tables,
>                 important_tablenames, excluded, jtablemap
>             ) = self._build_joins_for_select(tablemap, left)
>             tablemap = merge_tablemaps(tablemap, dict(**tables_to_merge))
>             tablemap = merge_tablemaps(tablemap, jtablemap)
>
>
>
> On Tue, Feb 27, 2018 at 4:30 PM, Richard Vézina <
> ml.richard.vez...@gmail.com> wrote:
>
>> In 17.01
>>
>> line 627
>>
>> if join and not left:
>>             cross_joins = iexcluded + list(itables_to_merge)
>>
>> cross_joins contains both tables involve in the query, which wasn't the
>> case in 16.11
>>
>> I follow up and it could come from
>>
>> helpers.methods.merge_tablempas() (introduced in 17.01) use
>> in _build_joins_for_select() or it could be caused by this piece of code
>> included in the former mention function :
>>
>>         tablemap = {}
>>         for item in param:
>>             if isinstance(item, Expression):
>>                 item = item.first
>>             key = item._tablename
>>             if tablemap.get(key, item) is not item:
>>                 raise ValueError('Name conflict in table list: %s' % key)
>>             tablemap[key] = item
>>
>> At that point code get difficult to understand what it does...
>>
>> Should we consider this a flaw in the actual code or  is this issue which
>> goes away when not doing empty query is related to the difficulty we were
>> having supporting the empty query syntax???
>>
>> I guess the answer to this question will resolve this definitely...
>>
>> Richard
>>
>> On Tue, Feb 27, 2018 at 2:11 PM, Richard Vézina <
>> ml.richard.vez...@gmail.com> wrote:
>>
>>> What causing the CROSS JOIN issue had been introduce between pyDAL 16.11
>>> and 17.01
>>>
>>> There is a compare of the 2 : https://github.com/web2py/py
>>> dal/compare/v16.11...v17.01
>>>
>>> Richard
>>>
>>> On Tue, Feb 27, 2018 at 12:59 PM, Richard Vézina <
>>> ml.richard.vez...@gmail.com> wrote:
>>>
>>>> At least there is a open issue on the book repo :
>>>> https://github.com/web2py/web2py-book/issues/346
>>>>
>>>> On Tue, Feb 27, 2018 at 12:57 PM, Richard Vézina <
>>>> ml.richard.vez...@gmail.com> wrote:
>>>>
>>>>> Here : https://github.com/web2py/pydal/issues/388
>>>>>
>>>>> I think the follow up update to the book and change log never occurs...
>>>>>
>>>>> I am fine with patching my code and make sure I don't leave empty
>>>>> query... But I am curious to know if this "CROSS JOIN table_name" addition
>>>>> could be avoid otherwise than providing non empty query... I mean it rough
>>>>> mistake...
>>>>>
>>>>> Richard
>>>>>
>>>>> On Tue, Feb 27, 2018 at 12:39 PM, Richard Vézina <
>>>>> ml.richard.vez...@gmail.com> wrote:
>>>>>
>>>>>> @Leonel, I recall about empty query beeing deprecated... But I can't
>>>>>> find any reference to it neither in change log of pyDAL nor web2py change
>>>>>> log... Niether the book...
>>>>>>
>>>>>> Which version of the DAL the support been dropped?
>>>>>>
>>>>>> Richard
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Tue, Feb 27, 2018 at 12:01 PM, Richard Vézina <
>>>>>> ml.richard.vez...@gmail.com> wrote:
>>>>>>
>>>>>>> In [6]: db(db.auth_user.id > 0)._select(db.auth_membership.group_id,
>>>>>>> join=db.auth_membership.on(db.auth_user.id ==
>>>>>>> db.auth_membership.user_id))
>>>>>>> Out[6]: 'SELECT "auth_membership"."group_id" FROM "auth_user" JOIN
>>>>>>> "auth_membership" ON ("auth_user"."id" = "auth_membership"."user_id") 
>>>>>>> WHERE
>>>>>>> ("auth_user"."id" > 0);'
>>>>>>>
>>>>>>> Seems to solve it...
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Tue, Feb 27, 2018 at 11:58 AM, Leonel Câmara <
>>>>>>> leonelcam...@gmail.com> wrote:
>>>>>>>
>>>>>>>> I believe we deprecated empty queries as they caused way too many
>>>>>>>> problems and bugs (e.g. common filters don't work).
>>>>>>>>
>>>>>>>> --
>>>>>>>> Resources:
>>>>>>>> - http://web2py.com
>>>>>>>> - http://web2py.com/book (Documentation)
>>>>>>>> - http://github.com/web2py/web2py (Source code)
>>>>>>>> - https://code.google.com/p/web2py/issues/list (Report Issues)
>>>>>>>> ---
>>>>>>>> You received this message because you are subscribed to the Google
>>>>>>>> Groups "web2py-users" group.
>>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>>> send an email to web2py+unsubscr...@googlegroups.com.
>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to