Hive连接产生笛卡尔集

简介:

在使用hive过程中遇到这样的一个异常:

FAILED: ParseException line 1:18 Failed to recognize predicate 'a'. Failed rule: 'kwInner' in join type specifier

执行的hql语句如下:

[root@javachen.com ~]# hive -e 'select a.* from t a, t b where a.id=b.id'

从异常信息中很难看出出错原因,hive.log中也没有打印出详细的异常对战信息。改用jdbc连接hive-server2,可以看到hive-server2中提示如下异常信息:

13/10/17 09:57:48 ERROR ql.Driver: FAILED: ParseException line 1:18 Failed to recognize predicate 'a'. Failed rule: 'kwInner' in join type specifier

org.apache.hadoop.hive.ql.parse.ParseException: line 1:18 Failed to recognize predicate 'a'. Failed rule: 'kwInner' in join type specifier

	at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:446)
	at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:441)
	at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:349)
	at org.apache.hadoop.hive.ql.Driver.compileAndRespond(Driver.java:355)
	at org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:95)
	at org.apache.hive.service.cli.operation.SQLOperation.prepare(SQLOperation.java:76)
	at org.apache.hive.service.cli.operation.SQLOperation.run(SQLOperation.java:114)
	at org.apache.hive.service.cli.session.HiveSessionImpl.executeStatement(HiveSessionImpl.java:194)
	at org.apache.hive.service.cli.CLIService.executeStatement(CLIService.java:155)
	at org.apache.hive.service.cli.thrift.ThriftCLIService.ExecuteStatement(ThriftCLIService.java:191)
	at org.apache.hive.service.cli.thrift.TCLIService$Processor$ExecuteStatement.getResult(TCLIService.java:1193)
	at org.apache.hive.service.cli.thrift.TCLIService$Processor$ExecuteStatement.getResult(TCLIService.java:1)
	at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:39)
	at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:39)
	at org.apache.hive.service.cli.thrift.TSetIpAddressProcessor.process(TSetIpAddressProcessor.java:38)
	at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:206)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

从异常信息可以看到是在编译hql语句进行语法解析时出现了错误,到底为什么会出现Failed rule: 'kwInner' in join type specifier这样的异常信息呢?

在eclipse中查找关键字并没有找到相应代码,在Hive.g 中查找关键字“kwInner”,可以看到如下内容:

joinToken
@init { msgs.push("join type specifier"); }
@after { msgs.pop(); }
    :
      KW_JOIN                     -> TOK_JOIN
    | kwInner  KW_JOIN            -> TOK_JOIN
    | KW_CROSS KW_JOIN            -> TOK_CROSSJOIN
    | KW_LEFT  KW_OUTER KW_JOIN   -> TOK_LEFTOUTERJOIN
    | KW_RIGHT KW_OUTER KW_JOIN   -> TOK_RIGHTOUTERJOIN
    | KW_FULL  KW_OUTER KW_JOIN   -> TOK_FULLOUTERJOIN
    | KW_LEFT  KW_SEMI  KW_JOIN   -> TOK_LEFTSEMIJOIN
    ;

从上面可以看出hive支持的连接包括:

  • join
  • inner join
  • cross join (as of Hive 0.10)
  • left outer join
  • right outer join
  • full outer join
  • left semi join

kwInner为什么是小写呢,其含义是什么呢?搜索关键字,找到如下代码:

kwInner
:
{input.LT(1).getText().equalsIgnoreCase("inner")}? Identifier;

上面的大概意思是找到输入左边的内容并判断其值在忽略大小写情况下是否等于inner,大概意思是hql语句中缺少inner关键字吧?修改下hql语句如下,然后执行:

[root@javachen.com ~]#  hive -e 'select a.* from t a inner join t b where a.id=b.id'

修改后的hql语句能够正常运行,并且变成了内连接。在JION接连查询中没有ON连接key而通过WHERE条件语句会产生笛卡尔集。

Hive本身是不支持笛卡尔集的,不能用select T1.*, T2.* from table1, table2这种语法。但有时候确实需要用到笛卡尔集的时候,可以用下面的语法来实现同样的效果:

select T1.*, T2.* from table1 T1 join table2 T2 where 1=1;

注意在Hive的Strict模式下不能用这种语法,因为这样会产生笛卡尔集,而这种模式禁止产生笛卡尔集。需要先用set hive.mapred.mode=nonstrict;设为非strict模式就可以用了,或者将where改为on连接。

select T1.*, T2.* from table1 T1 join table2 T2 on  T1.id=T2.id;

关于Strict Mode

Hive中的严格模式可以防止用户发出(可以有问题)的查询无意中造成不良的影响。 将hive.mapred.mode设置成strict可以禁止三种类型的查询:

1)、在一个分区表上,如果没有在WHERE条件中指明具体的分区,那么这是不允许的,换句话说,不允许在分区表上全表扫描。这种限制的原因是分区表通常会持非常大的数据集并且可能数据增长迅速,对这样的一个大表做全表扫描会消耗大量资源,必须要再WHERE过滤条件中具体指明分区才可以执行成功的查询。

2)、第二种是禁止执行有ORDER BY的排序要求但没有LIMIT语句的HiveQL查询。因为ORDER BY全局查询会导致有一个单一的reducer对所有的查询结果排序,如果对大数据集做排序,这将导致不可预期的执行时间,必须要加上limit条件才可以执行成功的查询。

3)、第三种是禁止产生笛卡尔集。在JION接连查询中没有ON连接key而通过WHERE条件语句会产生笛卡尔集,需要改为JOIN…ON语句。

目录
相关文章
|
SQL HIVE
DataGrip连接Hive执行DDL操作报错:「FAILED: ParseException line 1:5 cannot recognize input near 'show' 'indexes' 'on' in ddl statement」
DataGrip连接Hive执行DDL操作报错:「FAILED: ParseException line 1:5 cannot recognize input near 'show' 'indexes' 'on' in ddl statement」
627 0
DataGrip连接Hive执行DDL操作报错:「FAILED: ParseException line 1:5 cannot recognize input near 'show' 'indexes' 'on' in ddl statement」
|
4月前
|
SQL 分布式计算 JavaScript
Hive的JOIN连接
Hive的JOIN连接
68 5
|
6月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用问题之如何使用Flink SQL连接带有Kerberos认证的Hive
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
8月前
|
SQL DataWorks 网络安全
DataWorks操作报错合集之DataWorks连接Hive数据库时出现连接超时的问题如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
115 2
|
SQL HIVE Python
Window10 pyhive连接hive报错:Could not start SASL: b‘Error in sasl_client_start (-4) SASL(-4)
Window10 pyhive连接hive报错:Could not start SASL: b‘Error in sasl_client_start (-4) SASL(-4)
688 0
Window10 pyhive连接hive报错:Could not start SASL: b‘Error in sasl_client_start (-4) SASL(-4)
|
SQL 关系型数据库 MySQL
Mybatis-Plus(连接Hive)
Mybatis-Plus(连接Hive)
283 0
|
SQL 存储 大数据
大数据Hive Join连接查询
大数据Hive Join连接查询
143 0
|
SQL 数据库 HIVE
Python连接Hive数据库
Python连接Hive数据库
|
SQL 分布式计算 网络协议
hive连接被拒
connection refused
257 0
|
SQL Java 数据库连接
本地客户端 dbeaver-连接HIVE库
本地客户端 dbeaver-连接HIVE库 hive库管理套件
本地客户端 dbeaver-连接HIVE库