让PostgreSQL支持没有别名的子查询(Oracle兼容)

PostgreSQL里我们随便运行一个不带别名的子查询:

postgres=# select * from (select * from pg_class);
ERROR:  subquery in FROM must have an alias
LINE 1: select * from (select * from pg_class);
                      ^
HINT:  For example, FROM (SELECT ...) [AS] foo.
postgres=#

而带子查询的是这样:

postgres=# select amname from (select * from pg_am) as a limit 3;
 amname 
--------
 btree
 hash
 gist
(3 rows)

postgres=#

Oracle下,有无别名均可:

SQL> select * from (select * from tab);

TNAME			       TABTYPE	CLUSTERID
------------------------------ ------- ----------
COUNTRIES		       TABLE
DEPARTMENTS		       TABLE
EMPLOYEES		       TABLE
EMP_DETAILS_VIEW	       VIEW
JOBS			       TABLE
JOB_HISTORY		       TABLE
LOCATIONS		       TABLE
REGIONS 		       TABLE

8 rows selected.

SQL>

没什么大的影响,但如果遇到Oracle程序向PG迁移,改起来就有点罗嗦,这时候我们不妨让PG变化一下。

这个目标是非常明确,直接去源代码里边:grep -r "subquery in FROM must have an alias",发现它在 src/backend/parser/gram.y

沿着代码往下看,可以看到子查询别名为空时报错,办法就很直截了当了,未指定别名时给他产生一个。

出错代码替换为:

Alias *a = makeNode(Alias);
a->aliasname = "alias_xxxx";
n->alias = a;

编译之后运行:

template1=# select amname from (select * from pg_am) limit 3;
 amname 
--------
 btree
 hash
 gist
(3 rows)

template1=#

小打小闹修改PG就是如此简单,当然这里还有更多工作要做,比如别名应该随机生成而不是像这样写死。

template1=# select amname from (select * from pg_am), (select * from pg_database);
ERROR:  table name "alias_xxxx" specified more than once
template1=#

这肯定不是我们想要的结果


作为一个演示的例子,到此已经足够。


欢迎订阅国际社区中文邮件列表

欢迎使用云栖问答知识库



神州飞象(北京)数据科技有限公司,专业PostgreSQL产品与服务提供商


转载于:https://my.oschina.net/quanzl/blog/597140

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值