zabetak commented on code in PR #6523:
URL: https://github.com/apache/hive/pull/6523#discussion_r3750550419
##########
iceberg/iceberg-handler/src/test/results/positive/llap/iceberg_bucket_map_join_1.q.out:
##########
Review Comment:
I more or less understood the reason behind the changes in this .q.out file.
What I am not sure is if we are losing something in terms of test coverage due
to the changes in cardinalities.
```
-- Each query has 1 join that can be converted to bucket join.
-- One of the query receives the small table from Map vertex while the other
recives it from Reducer vertex.
-- 4 configs enfoce MapJoin to be converted to one of the following joins:
-- 1. BucketMapJoin, 2. MapJoin, 3. VectorBucketMapJoin, 4. VectorMapJoin
```
##########
ql/src/java/org/apache/hadoop/hive/ql/parse/type/HiveFunctionHelper.java:
##########
@@ -336,6 +339,11 @@ public RexNode getExpression(String functionText,
FunctionInfo fi,
RexUtil.flatten(call.getOperands(), call.getOperator()));
}
+ // Avoid creating incorrect expressions like $1 < NULL or $1 = NULL or
NULL = NULL
+ // which may be problematic for Calcite later on
+ RexSimplify rexSimplify = new RexSimplify(rexBuilder,
RelOptPredicateList.EMPTY, RexUtil.EXECUTOR);
+ expr = rexSimplify.simplifyComparisonWithNull(expr, RexUnknownAs.UNKNOWN);
+
return expr;
Review Comment:
```suggestion
return rexSimplify.simplifyComparisonWithNull(expr,
RexUnknownAs.UNKNOWN);
```
Small nit. Only apply if we need to update the PR
##########
ql/src/test/results/clientpositive/llap/allcolref_in_udf.q.out:
##########
@@ -76,10 +76,10 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: a
- filterExpr: (UDFToDouble(key) < 100.0D) (type: boolean)
+ filterExpr: ((UDFToDouble(key) < 100.0D) and
(UDFToDouble(key) + 1.0D) is not null) (type: boolean)
Statistics: Num rows: 500 Data size: 89000 Basic stats:
COMPLETE Column stats: COMPLETE
Filter Operator
- predicate: (UDFToDouble(key) < 100.0D) (type: boolean)
+ predicate: ((UDFToDouble(key) < 100.0D) and
(UDFToDouble(key) + 1.0D) is not null) (type: boolean)
Review Comment:
It seems that this change falls under "3 ) Some IS [NOT] NULL
simplifications have been removed" category. I understand why it occurs but it
feels slightly as a regression or missed simplification. The additional `IS NOT
NULL` predicate does not seem to affect the result of the expression.
It's not blocking for the upgrade but wondering if it deserves a follow-up
ticket in order to restore the simplification (if its possible).
##########
ql/src/test/results/clientpositive/llap/dynamic_partition_pruning.q.out:
##########
@@ -581,10 +581,10 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: srcpart
- filterExpr: CAST( ds AS DATE) is not null (type: boolean)
+ filterExpr: day(CAST( ds AS DATE)) is not null (type:
boolean)
Review Comment:
Is this a simplification regression? If we pass a DATE to the `day` function
can it change the nullability of the result?
##########
ql/src/test/results/clientpositive/llap/in_typecheck_char.q.out:
##########
@@ -390,7 +390,7 @@ POSTHOOK: Input: default@ax
CBO PLAN:
HiveProject(_c0=[$0])
HiveAggregate(group=[{}], agg#0=[count()])
- HiveFilter(condition=[IN($1, _UTF-16LE'a', _UTF-16LE'aa', _UTF-16LE'aaa',
_UTF-16LE'ab', _UTF-16LE'abc', _UTF-16LE'ac', _UTF-16LE'ba', _UTF-16LE'bb',
_UTF-16LE'bbb', _UTF-16LE'bc', _UTF-16LE'bca', _UTF-16LE'ca', _UTF-16LE'cab',
_UTF-16LE'cb', _UTF-16LE'cbc', _UTF-16LE'z')])
+ HiveFilter(condition=[IN($1, 'a ', 'aa ', 'aaa ', 'ab
', 'abc ', 'ac ', 'ba ', 'bb ', 'bbb ',
'bc ', 'bca ', 'ca ', 'cab ', 'cb ', 'cbc
', 'z ')])
Review Comment:
It's interesting that the literals in the physical plan below are already
padded. It means that correctness is probably not affected for Hive queries.
##########
ql/src/test/results/clientpositive/llap/external_jdbc_table2.q.out:
##########
@@ -716,7 +716,7 @@ STAGE PLANS:
hive.sql.query SELECT "ikey"
FROM (SELECT "ikey", "bkey", "dkey"
FROM "EXTERNAL_JDBC_SIMPLE_DERBY2_TABLE1") AS "t"
-WHERE ("bkey" = 10 AND "dkey" = 15.15 OR "bkey" = 20 AND "dkey" = 25.25) AND
"bkey" IN (10, 20) AND "dkey" IN (15.15, 25.25) AND "ikey" IS NOT NULL
+WHERE ("bkey" = 10 AND "dkey" = 1.515E1 OR "bkey" = 20 AND "dkey" = 2.525E1)
AND "bkey" IN (10, 20) AND "dkey" IN (1.515E1, 2.525E1) AND "ikey" IS NOT NULL
Review Comment:
It seems that the representation change of double and string literals does
not affect only the plans but also the actual SQL queries that we are pushing
down to various supported engines.
I guess we need to ensure that this change does not break the JDBC storage
handler so we may need a few tests for the supported DBMS (Postgres, MySQL,
MSSQL, Oracle). Since this test passes I guess that Derby coverage exists but
not sure if what holds for the rest. If there is documentation in the
respective databases that clearly states that this exponent literals are
supported then I don't insist in adding new test cases.
The proposed tests fit better in the Calcite repo rather than Hive so we
should log a CALCITE ticket if necessary.
##########
ql/src/test/results/clientpositive/llap/pointlookup6.q.out:
##########
@@ -99,6 +99,6 @@ POSTHOOK: Input: default@r_table
#### A masked pattern was here ####
CBO PLAN:
HiveProject(r_table.string_col=[$0])
- HiveFilter(condition=[OR(IS NULL(CAST($0):TIMESTAMP(9)),
IN(MINUTE(FLAG(MINUTE), CAST($0):TIMESTAMP(9)), 2, 10))])
+ HiveFilter(condition=[OR(IS NULL(MINUTE(FLAG(MINUTE),
CAST($0):TIMESTAMP(9))), IN(MINUTE(FLAG(MINUTE), CAST($0):TIMESTAMP(9)), 2,
10))])
Review Comment:
Can `MINUTE` affect the nullability of the result?
##########
ql/src/test/results/clientpositive/llap/input8.q.out:
##########
@@ -36,14 +36,14 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: src1
- Statistics: Num rows: 25 Data size: 191 Basic stats:
COMPLETE Column stats: COMPLETE
+ Statistics: Num rows: 25 Data size: 2150 Basic stats:
COMPLETE Column stats: COMPLETE
Select Operator
- expressions: null (type: string), null (type: int), null
(type: double)
+ expressions: null (type: string),
UDFToInteger((UDFToDouble(key) - null)) (type: int), null (type: double)
Review Comment:
This may be a regression at least for Hive. The CAST in Hive does not throw
an error so subtracting null will always lead to null I guess.
##########
ql/src/test/results/clientpositive/llap/stats_histogram.q.out:
##########
@@ -710,16 +710,16 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: test_stats
- filterExpr: (((d < 3.0) or (d > 7.0)) and (e > 0)) (type:
boolean)
+ filterExpr: ((e > 0) and ((d < 3.0) or (d > 7.0))) (type:
boolean)
Statistics: Num rows: 15 Data size: 1732 Basic stats:
COMPLETE Column stats: COMPLETE
Filter Operator
- predicate: (((d < 3.0) or (d > 7.0)) and (e > 0)) (type:
boolean)
- Statistics: Num rows: 8 Data size: 924 Basic stats:
COMPLETE Column stats: COMPLETE
+ predicate: ((e > 0) and ((d < 3.0) or (d > 7.0))) (type:
boolean)
+ Statistics: Num rows: 9 Data size: 1040 Basic stats:
COMPLETE Column stats: COMPLETE
Review Comment:
It's strange that predicate order affects the statistics. I guess it
shouldn't but this is minor and not directly relevant to the upgrade.
##########
ql/src/test/results/clientpositive/llap/vector_interval_mapjoin.q.out:
##########
@@ -206,26 +206,26 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: vectortab_a_1korc
- filterExpr: (dt is not null and CAST( ts AS DATE) is not
null and s is not null) (type: boolean)
+ filterExpr: ((dt - CAST( ts AS DATE)) is not null and s is
not null) (type: boolean)
Review Comment:
Can the substraction change nullability?
##########
ql/src/main/resources/saffron.properties:
##########
@@ -0,0 +1,22 @@
+# -----------------------------------------------------------------------------
+# Calcite JVM-wide defaults for Hive.
+#
+# This file is read by org.apache.calcite.config.CalciteSystemProperty's
+# static initializer at class-load time. Setting properties here rather
+# than via System.setProperty() eliminates a potential class-load-order race.
+# Command-line JVM flags (-Dcalcite.foo=bar) still override this file;
+# see CalciteSystemProperty#loadProperties for the merge order.
+# -----------------------------------------------------------------------------
+
+# Prevent Calcite from normalizing RexNode digests. Hive relies on the
+# un-normalized form for plan output stability.
+calcite.enable.rexnode.digest.normalize = false
+
+# Default charset definition: matches Hive's HiveTypeFactory#getDefaultCharset.
+# Value is little-endian: this matches
+# org.apache.calcite.util.ConversionUtil#NATIVE_UTF16_CHARSET_NAME on
+# every architecture Hive is deployed on in practice (x86, x86_64,
+# aarch64 in default mode). On a hypothetical big-endian JVM, override with
+# -Dcalcite.default.charset=UTF-16BE -Dcalcite.default.nationalcharset=UTF-16BE
Review Comment:
Do we expect the users to change this property? Apart from query plan
display what's the impact of this property in Hive runtime? Do we expect query
results to change? Can it affect correctness?
The `ConversionUtil#NATIVE_UTF16_CHARSET_NAME` that is used extensively in
the code base is initialized automatically based on the endianess of the
system. Is there a risk in harcoding the default charset to little endian here?
##########
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveRelFieldTrimmer.java:
##########
@@ -549,9 +550,8 @@ private ImmutableBitSet generateNewGroupset(Aggregate
aggregate, ImmutableBitSet
*/
private Aggregate rewriteGBConstantKeys(Aggregate aggregate, ImmutableBitSet
fieldsUsed,
ImmutableBitSet aggCallFields) {
- if ((aggregate.getIndicatorCount() > 0)
- || (aggregate.getGroupSet().isEmpty())
- || fieldsUsed.contains(aggregate.getGroupSet())) {
+ if (aggregate.getGroupSet().isEmpty()
+ || fieldsUsed.intersects(aggregate.getGroupSet())) {
Review Comment:
Is there a test case covering the added condition and the grouping sets?
##########
ql/pom.xml:
##########
@@ -365,6 +365,24 @@
<artifactId>hadoop-yarn-client</artifactId>
<optional>true</optional>
</dependency>
+ <!--
+ Runtime dependencies required by
org.apache.calcite.avatica:avatica-core:1.28.0
+ (pulled in by Calcite 1.42+): Avatica now uses Apache HttpComponents 5
for its
+ HTTP/JDBC transport, so hive-exec must bundle httpcore5/httpclient5 or
tests fail
+ with "NoClassDefFoundError: org/apache/hc/core5/util/Timeout". Avatica
declares
+ these as <scope>runtime</scope> transitively, but they must be declared
here
+ explicitly because Hive's enforcer bans org.apache.hc.core5/client5.**
imports
+ elsewhere and the hive-exec shade plugin only bundles ql-level
dependencies.
+ Can be removed once Hive migrates to HttpComponents 5 across the board.
+ -->
+ <dependency>
+ <groupId>org.apache.httpcomponents.core5</groupId>
+ <artifactId>httpcore5</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents.client5</groupId>
+ <artifactId>httpclient5</artifactId>
+ </dependency>
Review Comment:
Various other transitive dependencies from Calcite/Avatica are also added
explicitly to avoid classpath issues.
```
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value-annotations</artifactId>
</dependency>
```
I understand why we need to declare `httpcore5` here but I don't see the
connection with the enforcer checks. Can you please elaborate a bit more on
this?
The removal comment is also a bit confusing. I don't understand what needs
to be done after a global migration to httpcore5.
##########
ql/src/test/results/clientpositive/llap/auto_join13.q.out:
##########
@@ -87,7 +88,7 @@ STAGE PLANS:
sort order:
Statistics: Num rows: 1 Data size: 8 Basic
stats: COMPLETE Column stats: COMPLETE
value expressions: _col0 (type: bigint)
- Execution mode: vectorized, llap
+ Execution mode: llap
Review Comment:
The extra residual filter predicates seem to lead into loss of vectorization
so we may need to log a follow-up for the extra IS NOT NULL predicates.
##########
ql/src/test/results/clientpositive/llap/dynamic_partition_pruning.q.out:
##########
@@ -1885,37 +1885,40 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: srcpart_double_hour_n0
- filterExpr: ((UDFToDouble(hour) = 11.0D) and
UDFToDouble(UDFToInteger((hr / 2.0D))) is not null) (type: boolean)
+ filterExpr: ((UDFToDouble(hour) = 11.0D) and hr is not null)
(type: boolean)
Statistics: Num rows: 2 Data size: 188 Basic stats: COMPLETE
Column stats: COMPLETE
Filter Operator
- predicate: ((UDFToDouble(hour) = 11.0D) and
UDFToDouble(UDFToInteger((hr / 2.0D))) is not null) (type: boolean)
+ predicate: ((UDFToDouble(hour) = 11.0D) and hr is not
null) (type: boolean)
Statistics: Num rows: 1 Data size: 94 Basic stats:
COMPLETE Column stats: COMPLETE
Select Operator
expressions: UDFToDouble(UDFToInteger((hr / 2.0D)))
(type: double)
outputColumnNames: _col0
Statistics: Num rows: 1 Data size: 8 Basic stats:
COMPLETE Column stats: COMPLETE
- Reduce Output Operator
- key expressions: _col0 (type: double)
- null sort order: z
- sort order: +
- Map-reduce partition columns: _col0 (type: double)
+ Filter Operator
+ predicate: _col0 is not null (type: boolean)
Review Comment:
This is the old predicate disguised as a new Filter operator.
##########
ql/src/test/results/clientpositive/llap/dynamic_partition_pruning.q.out:
##########
@@ -2301,10 +2307,10 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: srcpart
- filterExpr: UDFToDouble(hr) is not null (type: boolean)
+ filterExpr: (UDFToDouble(hr) * 2.0D) is not null (type:
boolean)
Review Comment:
Is this a simplification regression? Can the multiplication with a constant
change the nullability of the result?
##########
ql/src/test/results/clientpositive/llap/dynamic_partition_pruning.q.out:
##########
@@ -1885,37 +1885,40 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: srcpart_double_hour_n0
- filterExpr: ((UDFToDouble(hour) = 11.0D) and
UDFToDouble(UDFToInteger((hr / 2.0D))) is not null) (type: boolean)
+ filterExpr: ((UDFToDouble(hour) = 11.0D) and hr is not null)
(type: boolean)
Review Comment:
This simplification is called out in the description of the PR: "1 ) New IS
NOT NULL simplifications involving CAST, like in: dynamic_partition_pruning.q"
However, as indicated elsewhere the predicate is not going away but rather
moves a bit higher up disguised as a new `Filter` operator.
##########
ql/src/test/results/clientpositive/llap/auto_join2.q.out:
##########
@@ -118,19 +121,22 @@ STAGE PLANS:
Statistics: Num rows: 500 Data size: 49500 Basic
stats: COMPLETE Column stats: COMPLETE
value expressions: _col0 (type: string)
Filter Operator
- predicate: (key is not null and UDFToDouble(key) is not
null) (type: boolean)
+ predicate: key is not null (type: boolean)
Review Comment:
Instead of one `Filter` operator with a single conjunction we now have two
`Filter` operators with the conjunction split among them. In terms of
correctness and performance it shouldn't matter much but it is a bit strange
that this pattern appears despite the fact that we are using the
`FilterMergeRule`.
##########
ql/src/test/results/clientpositive/llap/explainuser_1.q.out:
##########
@@ -6562,7 +6562,7 @@ Stage-0
<-Select Operator [SEL_5] (rows=500 width=12)
Output:["_col0","_col1"]
Filter Operator [FIL_19] (rows=500 width=87)
- predicate:UDFToDouble(key) is not null
+ predicate:(UDFToDouble(key) + 1.0D) is not null
Review Comment:
(Not sure if already left the comment elsewhere)
Can the addition of a constant to a DOUBLE change the nullability of the
result? I guess it can lead to +Infinity but I am not sure if the latter is
considered null. I guess we don't have tests around this IS [NOT] NULL with
DOUBLE overflows/underflows so we may need to log a follow-up ticket to
establish the expected behavior in Hive cause this change may have correctness
implications.
##########
ql/src/test/results/clientpositive/llap/interval_3.q.out:
##########
@@ -159,10 +159,10 @@ STAGE PLANS:
Map Operator Tree:
TableScan
alias: d1
- filterExpr: CAST( d_date AS DATE) is not null (type: boolean)
+ filterExpr: (((((((CAST( d_date AS DATE) + INTERVAL'1-0') +
INTERVAL'0-2') + INTERVAL'5 00:00:00.000000000') + INTERVAL'0
04:00:00.000000000') + INTERVAL'0 00:10:00.000000000') + INTERVAL'0
00:00:09.000000000') is not null and (CAST( d_date AS DATE) + INTERVAL'1-2') is
not null) (type: boolean)
Statistics: Num rows: 1 Data size: 188 Basic stats: COMPLETE
Column stats: NONE
Filter Operator
- predicate: CAST( d_date AS DATE) is not null (type:
boolean)
+ predicate: (((((((CAST( d_date AS DATE) + INTERVAL'1-0') +
INTERVAL'0-2') + INTERVAL'5 00:00:00.000000000') + INTERVAL'0
04:00:00.000000000') + INTERVAL'0 00:10:00.000000000') + INTERVAL'0
00:00:09.000000000') is not null and (CAST( d_date AS DATE) + INTERVAL'1-2') is
not null) (type: boolean)
Review Comment:
The loss of simplifications around IS NOT NULL seems to have a big impact in
the Hive plans. We have to check if more conservative behavior makes sense for
Hive.
##########
ql/src/test/results/clientpositive/llap/external_jdbc_table_perf.q.out:
##########
@@ -3212,7 +3212,7 @@ WHERE "d_year" = 2000 AND "d_moy" = 1 AND "d_date_sk" IS
NOT NULL) AS "t10" ON "
hive.sql.query SELECT "i_item_id"
FROM (SELECT "i_item_id", "i_color"
FROM "ITEM") AS "t"
-WHERE "i_color" IN ('chiffon', 'lace', 'orchid') AND "i_item_id" IS NOT NULL
Review Comment:
This is a correctness fix right? It means that previously Hive was returning
wrong results. This test does not involve data otherwise we would see change in
the returned rows.
##########
ql/src/test/results/clientpositive/llap/materialized_view_rewrite_4.q.out:
##########
Review Comment:
Based on the git history the MV rewrite for the following query in
materialized_view_rewrite_4.q was working fine when the test was introduced.
```sql
select emps.deptno, count(distinct salary) as s
from emps
join dependents on (emps.empid = dependents.empid)
group by dependents.empid, emps.deptno
```
It seems that the rewritting was "broken" during
[HIVE-18839](https://issues.apache.org/jira/browse/HIVE-18839?focusedCommentId=16426416&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16426416)
and HIVE-19114 was raised as a follow-up.
The calcite upgrade restored the rewritting so we should also mark
HIVE-19114 as resolved when the PR is merged.
##########
ql/src/test/results/clientpositive/llap/udf_between.q.out:
##########
@@ -84,9 +84,9 @@ STAGE PLANS:
Processor Tree:
TableScan
alias: src
- filterExpr: (UDFToDouble(key) + 100.0D) NOT BETWEEN 100.0D AND
200.0D (type: boolean)
Review Comment:
It is interesting that we had NOT BETWEEN in the plan. I was under the
impression that this does not appear in the plan at all. Not super urgent but
would be curious to understand how this was introduced since it is relevant on
other improvements around BETWEEN that are currently under discussion in other
JIRA tickets.
##########
ql/src/test/results/clientpositive/perf/tpcds30tb/json/query30.q.out:
##########
@@ -1947,7 +1947,7 @@
"name": null
}
],
- "rowCount": 36000000
Review Comment:
The rowCount estimation has increased by many orders of magnitude. Are these
changes due to CALCITE-7083? It the new estimation better or worse?
##########
ql/src/test/results/clientpositive/perf/tpcds30tb/json/query38.q.out:
##########
@@ -1194,7 +1194,7 @@
"name": null
}
],
- "rowCount": 80000000
Review Comment:
The huge increase in rowCount estimation is somewhat worrisome. I am afraid
when these numbers are combined with other computations we may lead to inf
values.
--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]