PostgreSQL标识符如何作为函数参数

看PostgreSQL文档:

SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
Result: 20
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 21

参数感觉有些诡异,但看起来很智能。

打开psql,并不存在extract这个函数

flying=# \df extract
                       List of functions
 Schema | Name | Result data type | Argument data types | Type
--------+------+------------------+---------------------+------
(0 rows)

flying=#

运行刚才的例子,会发现返回结果的标题是date_part,而不是像正常函数那样标题是函数名本身。

flying=# SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
 date_part
-----------
        20
(1 row)

flying=#

打开语法引擎gram.y,EXTRACT是一个列名关键字(含义见col_name_keyword注释)

EXTRACT '(' extract_list ')'
  {
    $$ = (Node *) makeFuncCall(SystemFuncName("date_part"), $3, @1);
  }

它是个语法结构而不是一个真正的函数,被语法引擎转换为date_part函数的调用,所以才会出现我们前边所说的没有函数定义,执行结果标题是date_part的现象。这里标题可以用别名封装一下,效果会更真实,但也并没有必要,我们知道可以做到就可以了。

还没说到标识符作参数,下边就是,我们来看 extract_list 定义

extract_list:
			extract_arg FROM a_expr
				{
					$$ = list_make2(makeStringConst($1, @1), $3);
				}
			| /*EMPTY*/								{ $$ = NIL; }
		;

/* Allow delimited string Sconst in extract_arg as an SQL extension.
 * - thomas 2001-04-12
 */
extract_arg:
			IDENT									{ $$ = $1; }
			| YEAR_P								{ $$ = "year"; }
			| MONTH_P								{ $$ = "month"; }
			| DAY_P									{ $$ = "day"; }
			| HOUR_P								{ $$ = "hour"; }
			| MINUTE_P								{ $$ = "minute"; }
			| SECOND_P								{ $$ = "second"; }
			| Sconst								{ $$ = $1; }
		;

从 extract_arg 可以看到,标识符并不是真的传给了函数,跟extract一样,只是语法封装。

想定义Sybase的datepart、dateadd、datediff效果,知道怎么做了吧?

datepart(ms, timestamp value) 用FROM分隔和逗号分隔没什么区别,上篇文章就提到过,gram.y里边也有大把例子。

缺点:定义太多这类语法转义(可能这么叫、错了在心里自行纠正),引入很多关键字,也许不是好事,至少语法部分代码维护要麻烦一些。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值