Greenplum,HAWQ interval parser带来的问题 - TPCH 测试注意啦

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

Greenplum,HAWQ interval parser带来的问题 - TPCH 测试注意啦

作者

digoal

日期

2016-10-11

标签

Greenplum , PostgreSQL , interval , parser


背景

interval是用来表达时间间隔的数据类型,比如1年,或者1分钟,或者1天零多少小时分钟等。

postgres=# select interval '100 year 2 month 1 day 1:00:01.11'; 
              interval              
------------------------------------
 100 years 2 mons 1 day 01:00:01.11
(1 row)

interval可以与时间,日期类型加减。

postgres=# select now()+interval '100 year 2 month 1 day 1:00:01.11'; 
           ?column?            
-------------------------------
 2116-12-12 20:06:48.391422+08
(1 row)

interval的用法可参考

https://www.postgresql.org/docs/9.6/static/functions-datetime.html

interval parser不同版本的差异

1. PostgreSQL 8.3以及以前的版本不能解释放在单引号外面的单位

$psql -h 127.0.0.1 -p 35432 -U digoal postgres
psql (8.3.23)
Type "help" for help.

postgres=# select now(), now()+interval '1 year', now()+interval '1' year;
              now              |           ?column?            |           ?column?            
-------------------------------+-------------------------------+-------------------------------
 2016-10-11 19:02:46.881375+08 | 2017-10-11 19:02:46.881375+08 | 2016-10-11 19:02:46.881375+08
(1 row)
postgres=# select interval '100' year; 
 interval 
----------
 00:00:00
(1 row)

2. 8.4以及以后的版本则支持放在外面的单位的写法。

psql (9.4.9)
Type "help" for help.


postgres=# select now(), now()+interval '1 year', now()+interval '1' year;
              now              |           ?column?            |           ?column?            
-------------------------------+-------------------------------+-------------------------------
 2016-10-11 19:08:29.365853+08 | 2017-10-11 19:08:29.365853+08 | 2017-10-11 19:08:29.365853+08
(1 row)

postgres=# select interval '100' year; 
 interval  
-----------
 100 years
(1 row)

postgres=# select interval '100' hour; 
 interval  
-----------
 100:00:00
(1 row)

patch在这里
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=70530c808bf8eaba2a41a28c9dc7b96dcc3b6c51

Adjust the parser to accept the typename syntax INTERVAL ... SECOND(n)
and the literal syntax INTERVAL 'string' ... SECOND(n), as required by the
SQL standard.  Our old syntax put (n) directly after INTERVAL, which was
a mistake, but will still be accepted for backward compatibility as well
as symmetry with the TIMESTAMP cases.

Change intervaltypmodout to show it in the spec's way, too.  (This could
potentially affect clients, if there are any that analyze the typmod of an
INTERVAL in any detail.)

Also fix interval input to handle 'min:sec.frac' properly; I had overlooked
this case in my previous patch.

Document the use of the interval fields qualifier, which up to now we had
never mentioned in the docs.  (I think the omission was intentional because
it didn't work per spec; but it does now, or at least close enough to be
credible.)

tpch的QUERY造句

tpch的dbgen产生的query用的是带单位的写法,导致没有出现加减。

涉及的SQL如下

10.explain.sql: and o_orderdate < date '1993-04-01' + interval '3' month
12.explain.sql: and l_receiptdate < date '1995-01-01' + interval '1' year
14.explain.sql: and l_shipdate < date '1995-08-01' + interval '1' month
15.explain.sql:         and l_shipdate < date '1997-03-01' + interval '3' month
1.explain.sql:  l_shipdate <= date '1998-12-01' - interval '78' day
20.explain.sql:                                 and l_shipdate < date '1994-01-01' + interval '1' year
4.explain.sql:  and o_orderdate < date '1995-03-01' + interval '3' month
5.explain.sql:  and o_orderdate < date '1997-01-01' + interval '1' year
6.explain.sql:  and l_shipdate < date '1997-01-01' + interval '1' year

例子

-- using 1474112033 as a seed to the RNG


select
        l_returnflag,
        l_linestatus,
        sum(l_quantity) as sum_qty,
        sum(l_extendedprice) as sum_base_price,
        sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
        sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
        avg(l_quantity) as avg_qty,
        avg(l_extendedprice) as avg_price,
        avg(l_discount) as avg_disc,
        count(*) as count_order
from
        lineitem
where
        l_shipdate <= date '1998-12-01' - interval '78' day
group by
        l_returnflag,
        l_linestatus
order by
        l_returnflag,
        l_linestatus
LIMIT 1;

这些SQL直接影响了TPCH的测试结果。

请务必修正query后再执行。

interval 的 io函数

src/backend/utils/adt/timestamp.c

/* interval_in()
 * Convert a string to internal form.
 *
 * External format(s):
 *      Uses the generic date/time parsing and decoding routines.
 */
Datum
interval_in(PG_FUNCTION_ARGS)
{
        char       *str = PG_GETARG_CSTRING(0);

#ifdef NOT_USED
        Oid                     typelem = PG_GETARG_OID(1);
#endif
        int32           typmod = PG_GETARG_INT32(2);
        Interval   *result;
        fsec_t          fsec;
        struct pg_tm tt,
                           *tm = &tt;
        int                     dtype;
        int                     nf;
        int                     range;
        int                     dterr;
        char       *field[MAXDATEFIELDS];
        int                     ftype[MAXDATEFIELDS];
        char            workbuf[256];

        tm->tm_year = 0;
        tm->tm_mon = 0;
        tm->tm_mday = 0;
        tm->tm_hour = 0;
        tm->tm_min = 0;
        tm->tm_sec = 0;
        fsec = 0;

        if (typmod >= 0)
                range = INTERVAL_RANGE(typmod);
        else
                range = INTERVAL_FULL_RANGE;

        dterr = ParseDateTime(str, workbuf, sizeof(workbuf), field,
                                                  ftype, MAXDATEFIELDS, &nf);
        if (dterr == 0)
                dterr = DecodeInterval(field, ftype, nf, range,
                                                           &dtype, tm, &fsec);

        /* if those functions think it's a bad format, try ISO8601 style */
        if (dterr == DTERR_BAD_FORMAT)
                dterr = DecodeISO8601Interval(str,
                                                                          &dtype, tm, &fsec);

        if (dterr != 0)
        {
                if (dterr == DTERR_FIELD_OVERFLOW)
                        dterr = DTERR_INTERVAL_OVERFLOW;
                DateTimeParseError(dterr, str, "interval");
        }

        result = (Interval *) palloc(sizeof(Interval));

        switch (dtype)
        {
                case DTK_DELTA:
                        if (tm2interval(tm, fsec, result) != 0)
                                ereport(ERROR,
                                                (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
                                                 errmsg("interval out of range")));
                        break;

                case DTK_INVALID:
                        ereport(ERROR,
                                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                          errmsg("date/time value \"%s\" is no longer supported", str)));
                        break;

                default:
                        elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"",
                                 dtype, str);
        }

        AdjustIntervalForTypmod(result, typmod);

        PG_RETURN_INTERVAL_P(result);
}

/* interval_out()
 * Convert a time span to external form.
 */
Datum
interval_out(PG_FUNCTION_ARGS)
{
        Interval   *span = PG_GETARG_INTERVAL_P(0);
        char       *result;
        struct pg_tm tt,
                           *tm = &tt;
        fsec_t          fsec;
        char            buf[MAXDATELEN + 1];

        if (interval2tm(*span, tm, &fsec) != 0)
                elog(ERROR, "could not convert interval to tm");

        EncodeInterval(tm, fsec, IntervalStyle, buf);

        result = pstrdup(buf);
        PG_RETURN_CSTRING(result);
}

Count

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
4月前
|
SQL 数据可视化 关系型数据库
Grafana【实践 01】Greenplum和InfluxDB数据源添加及仪表盘测试
Grafana【实践 01】Greenplum和InfluxDB数据源添加及仪表盘测试
116 0
|
4月前
|
算法 关系型数据库 API
Python【算法中心 02】Web框架Django管理页面使用(管理员账号创建+API使用+应用添加)GreenPlum数据库引擎及API测试
Python【算法中心 02】Web框架Django管理页面使用(管理员账号创建+API使用+应用添加)GreenPlum数据库引擎及API测试
42 0
|
弹性计算 关系型数据库 数据库
Deepgreen(Greenplum) 多机部署测试 , TPC-H VS citus
标签 PostgreSQL , deepgreen , greenplum , citus , tpch , 多机部署 背景 多机部署deepgreen,与greenplum部署方法类似。
2211 0
|
固态存储 关系型数据库 MySQL
|
关系型数据库 数据库
Greenplum TPC-H测试
请参考如下 http://www.tpc.org/information/current_specifications.asp https://github.com/digoal/pg_tpch 下载tpch TPC-H V2.17.1 pdf Download D
18056 0
|
9天前
|
测试技术 C语言
网站压力测试工具Siege图文详解
网站压力测试工具Siege图文详解
19 0
|
1月前
|
JavaScript jenkins 测试技术
这10款性能测试工具,收藏起来,测试人的工具箱!
这10款性能测试工具,收藏起来,测试人的工具箱!
|
1月前
|
人工智能 监控 测试技术
利用AI辅助工具提升软件测试效率
【2月更文挑战第17天】 随着科技的不断发展,人工智能(AI)在各个领域的应用越来越广泛。在软件测试领域,AI技术也发挥着重要作用。本文将探讨如何利用AI辅助工具提升软件测试效率,包括自动化测试、智能缺陷识别和预测等方面。通过引入AI技术,软件测试过程将变得更加高效、准确和可靠。
163 1
|
1月前
|
Web App开发 前端开发 测试技术
探索自动化测试工具:Selenium的威力与应用
探索自动化测试工具:Selenium的威力与应用
探索自动化测试工具:Selenium的威力与应用
|
29天前
|
测试技术
现代软件测试中的自动化工具与挑战
传统软件测试面临着越来越复杂的系统架构和不断增长的测试需求,自动化测试工具应运而生。本文将探讨现代软件测试中自动化工具的应用和挑战,深入分析其优势与局限性,为软件测试领域的发展提供思路和启示。