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

简介:

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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
SQL 数据可视化 关系型数据库
Grafana【实践 01】Greenplum和InfluxDB数据源添加及仪表盘测试
Grafana【实践 01】Greenplum和InfluxDB数据源添加及仪表盘测试
487 0
|
算法 关系型数据库 API
Python【算法中心 02】Web框架Django管理页面使用(管理员账号创建+API使用+应用添加)GreenPlum数据库引擎及API测试
Python【算法中心 02】Web框架Django管理页面使用(管理员账号创建+API使用+应用添加)GreenPlum数据库引擎及API测试
243 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
18621 2
|
弹性计算 关系型数据库 数据库
Deepgreen(Greenplum) 多机部署测试 , TPC-H VS citus
标签 PostgreSQL , deepgreen , greenplum , citus , tpch , 多机部署 背景 多机部署deepgreen,与greenplum部署方法类似。
2566 0
|
SQL 存储 数据库
Tpc-h测试greenplum性能
Tpc-h测试greenplum性能
4632 0
|
固态存储 关系型数据库 MySQL
|
关系型数据库 中间件 测试技术
|
11月前
|
数据可视化 前端开发 测试技术
接口测试新选择:Postman替代方案全解析
在软件开发中,接口测试工具至关重要。Postman长期占据主导地位,但随着国产工具的崛起,越来越多开发者转向更适合中国市场的替代方案——Apifox。它不仅支持中英文切换、完全免费不限人数,还具备强大的可视化操作、自动生成文档和API调试功能,极大简化了开发流程。
|
6月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
1059 23
|
8月前
|
SQL 安全 测试技术
2025接口测试全攻略:高并发、安全防护与六大工具实战指南
本文探讨高并发稳定性验证、安全防护实战及六大工具(Postman、RunnerGo、Apipost、JMeter、SoapUI、Fiddler)选型指南,助力构建未来接口测试体系。接口测试旨在验证数据传输、参数合法性、错误处理能力及性能安全性,其重要性体现在早期发现问题、保障系统稳定和支撑持续集成。常用方法包括功能、性能、安全性及兼容性测试,典型场景涵盖前后端分离开发、第三方服务集成与数据一致性检查。选择合适的工具需综合考虑需求与团队协作等因素。
1296 24