[ 
https://issues.apache.org/jira/browse/HIVE-25758?focusedWorklogId=719996&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-719996
 ]

ASF GitHub Bot logged work on HIVE-25758:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 03/Feb/22 10:17
            Start Date: 03/Feb/22 10:17
    Worklog Time Spent: 10m 
      Work Description: asolimando commented on a change in pull request #2966:
URL: https://github.com/apache/hive/pull/2966#discussion_r798411704



##########
File path: 
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveJoinPushTransitivePredicatesRule.java
##########
@@ -144,27 +146,70 @@ public void onMatch(RelOptRuleCall call) {
     }
 
     // We need to filter i) those that have been pushed already as stored in 
the join,
-    // and ii) those that were already in the subtree rooted at child
-    ImmutableList<RexNode> toPush = 
HiveCalciteUtil.getPredsNotPushedAlready(predicatesToExclude,
-            child, valids);
-    return toPush;
+    // ii) those that were already in the subtree rooted at child,
+    // iii) predicates that are not safe for transitive inference.
+    //
+    // There is no formal definition of safety for predicate inference, only 
an empirical one.

Review comment:
       The change does not reinforce the dependency on the registry. If you 
check the call, we are filtering candidate predicates coming from 
`HiveRelMdPredicates`, which is not linked to the registry at all. The 
predicates in the registry are used to add another filtering step (to remove 
"duplicates"), but the two steps are totally independent, they are just 
performed within the same method.
   
   This said, I agree that keeping a global state is a problem, and should be 
avoided. The current implementation is also faulty under some respects.
   
   The motivation for storing predicates in the registry is given in 
[HIVE-12478](https://issues.apache.org/jira/browse/HIVE-12478?focusedCommentId=15047639&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-15047639).
   
   Since predicates can be modified (pushed past project/setOp/joins/aggregate, 
they can be simplified or merged), we can try to push them transitively as it 
happens in this OOM cases.
   
   But, as I was saying, the current implementation is faulty, since even the 
registry is not enough, because most of the other rules they don't know about 
it, they will alter the predicates, but they won't register them into the 
registry. Making all those rules aware of the registry would increase the 
coupling, hence not an option IMO.
   
   The registry main use was to prevent firing the same rule against the same 
rel multiple times, but even this use is not complete, since rels are modified 
along the way, and we don't update the registry accordingly. For instance, a 
join condition is updated, the new join has a fresh rel-id, the registry will 
try to re-apply `HiveJoinPushTransitivePredicatesRule`, and if the predicates 
were modified too, this will also escape the duplicate check based on the 
`registry.getPushedPredicates(join)`, and we can have a loop).
   
   On the other hand, I don't see how we can prevent such loops without storing 
a global state. But for this global state to work, each and every rule must be 
aware of it, which is totally not doable IMO, which is also the line in Calcite.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: gitbox-unsubscr...@hive.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


Issue Time Tracking
-------------------

    Worklog Id:     (was: 719996)
    Time Spent: 50m  (was: 40m)

> OOM due to recursive application of CBO rules
> ---------------------------------------------
>
>                 Key: HIVE-25758
>                 URL: https://issues.apache.org/jira/browse/HIVE-25758
>             Project: Hive
>          Issue Type: Bug
>          Components: CBO, Query Planning
>    Affects Versions: 4.0.0
>            Reporter: Alessandro Solimando
>            Assignee: Alessandro Solimando
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 50m
>  Remaining Estimate: 0h
>
>  
> Reproducing query is as follows:
> {code:java}
> create table test1 (act_nbr string);
> create table test2 (month int);
> create table test3 (mth int, con_usd double);
> EXPLAIN
>    SELECT c.month,
>           d.con_usd
>    FROM
>      (SELECT 
> cast(regexp_replace(substr(add_months(from_unixtime(unix_timestamp(), 
> 'yyyy-MM-dd'), -1), 1, 7), '-', '') AS int) AS month
>       FROM test1
>       UNION ALL
>       SELECT month
>       FROM test2
>       WHERE month = 202110) c
>    JOIN test3 d ON c.month = d.mth; {code}
>  
> Different plans are generated during the first CBO steps, last being:
> {noformat}
> 2021-12-01T08:28:08,598 DEBUG [a18191bb-3a2b-4193-9abf-4e37dd1996bb main] 
> parse.CalcitePlanner: Plan after decorre
> lation:
> HiveProject(month=[$0], con_usd=[$2])
>   HiveJoin(condition=[=($0, $1)], joinType=[inner], algorithm=[none], 
> cost=[not available])
>     HiveProject(month=[$0])
>       HiveUnion(all=[true])
>         
> HiveProject(month=[CAST(regexp_replace(substr(add_months(FROM_UNIXTIME(UNIX_TIMESTAMP,
>  _UTF-16LE'yyyy-MM-d
> d':VARCHAR(2147483647) CHARACTER SET "UTF-16LE"), -1), 1, 7), 
> _UTF-16LE'-':VARCHAR(2147483647) CHARACTER SET "UTF-
> 16LE", _UTF-16LE'':VARCHAR(2147483647) CHARACTER SET "UTF-16LE")):INTEGER])
>           HiveTableScan(table=[[default, test1]], table:alias=[test1])
>         HiveProject(month=[$0])
>           HiveFilter(condition=[=($0, CAST(202110):INTEGER)])
>             HiveTableScan(table=[[default, test2]], table:alias=[test2])
>     HiveTableScan(table=[[default, test3]], table:alias=[d]){noformat}
>  
> Then, the HEP planner will keep expanding the filter expression with 
> redundant expressions, such as the following, where the identical CAST 
> expression is present multiple times:
>  
> {noformat}
> rel#118:HiveFilter.HIVE.[].any(input=HepRelVertex#39,condition=IN(CAST(regexp_replace(substr(add_months(FROM_UNIXTIME(UNIX_TIMESTAMP,
>  _UTF-16LE'yyyy-MM-dd':VARCHAR(2147483647) CHARACTER SET "UTF-16LE"), -1), 1, 
> 7), _UTF-16LE'-':VARCHAR(2147483647) CHARACTER SET "UTF-16LE", 
> _UTF-16LE'':VARCHAR(2147483647) CHARACTER SET "UTF-16LE")):INTEGER, 
> CAST(regexp_replace(substr(add_months(FROM_UNIXTIME(UNIX_TIMESTAMP, 
> _UTF-16LE'yyyy-MM-dd':VARCHAR(2147483647) CHARACTER SET "UTF-16LE"), -1), 1, 
> 7), _UTF-16LE'-':VARCHAR(2147483647) CHARACTER SET "UTF-16LE", 
> _UTF-16LE'':VARCHAR(2147483647) CHARACTER SET "UTF-16LE")):INTEGER, 
> 202110)){noformat}
>  
> The problem seems to come from a bad interaction of at least 
> _HiveFilterProjectTransposeRule_ and 
> {_}HiveJoinPushTransitivePredicatesRule{_}, possibly more.
> Most probably then UNION part can be removed and the reproducer be simplified 
> even further.
>  



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to