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

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
7月前
|
SQL 数据可视化 关系型数据库
Grafana【实践 01】Greenplum和InfluxDB数据源添加及仪表盘测试
Grafana【实践 01】Greenplum和InfluxDB数据源添加及仪表盘测试
192 0
|
7月前
|
算法 关系型数据库 API
Python【算法中心 02】Web框架Django管理页面使用(管理员账号创建+API使用+应用添加)GreenPlum数据库引擎及API测试
Python【算法中心 02】Web框架Django管理页面使用(管理员账号创建+API使用+应用添加)GreenPlum数据库引擎及API测试
113 0
|
关系型数据库 数据库
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
18243 2
|
弹性计算 关系型数据库 数据库
Deepgreen(Greenplum) 多机部署测试 , TPC-H VS citus
标签 PostgreSQL , deepgreen , greenplum , citus , tpch , 多机部署 背景 多机部署deepgreen,与greenplum部署方法类似。
2358 0
|
SQL 存储 数据库
Tpc-h测试greenplum性能
Tpc-h测试greenplum性能
4472 0
|
固态存储 关系型数据库 MySQL
|
关系型数据库 中间件 测试技术
|
28天前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
55 3
|
2月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
71 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
3月前
|
移动开发 JSON Java
Jmeter实现WebSocket协议的接口测试方法
WebSocket协议是HTML5的一种新协议,实现了浏览器与服务器之间的全双工通信。通过简单的握手动作,双方可直接传输数据。其优势包括极小的头部开销和服务器推送功能。使用JMeter进行WebSocket接口和性能测试时,需安装特定插件并配置相关参数,如服务器地址、端口号等,还可通过CSV文件实现参数化,以满足不同测试需求。
256 7
Jmeter实现WebSocket协议的接口测试方法