已合并
解决yearweek导入导出报错问题 #2362
laishenghao创建于 1月24日
解决yearweek导入导出报错问题 #2362
已合并
laishenghao创建于 1月24日
5 个文件变更+147-1
@@ -102,3 +102,55 @@ drop table t_timestamp5;
102drop table t_timestamp6;102drop table t_timestamp6;
103reset current_schema;103reset current_schema;
104drop schema test_timestampn cascade;104drop schema test_timestampn cascade;
105+-- test yearweek with timestamps
106+drop table if exists person_track_info;
107+NOTICE: table "person_track_info" does not exist, skipping
108+CREATE TABLE person_track_info (
109+ "ID" "uint8"(20) NOT NULL,
110+ "SOURCE_ID" "uint8"(20),
111+ "OCCURRENCE_TIME" timestamp(6) without time zone NOT NULL,
112+ "OCCURRENCE_TIMEtz" timestamp(6) with time zone NOT NULL
113+)
114+PARTITION BY RANGE ("yearweek"(("OCCURRENCE_TIME")))
115+(
116+ PARTITION "part202549" VALUES LESS THAN ('202550'),
117+ PARTITION "part202550" VALUES LESS THAN ('202551'),
118+ PARTITION "part202551" VALUES LESS THAN ('202552'),
119+ PARTITION "part202552" VALUES LESS THAN ('202601'),
120+ PARTITION "part202601" VALUES LESS THAN ('202602'),
121+ PARTITION "part202602" VALUES LESS THAN ('202603'),
122+ PARTITION "part202650" VALUES LESS THAN ('202650')
123+)
124+ENABLE ROW MOVEMENT;
125+select pg_get_tabledef('person_track_info');
126+ pg_get_tabledef
127+----------------------------------------------------------------
128+ SET search_path = public; +
129+ CREATE TABLE person_track_info ( +
130+ "ID" uint8(20) NOT NULL, +
131+ "SOURCE_ID" uint8(20), +
132+ "OCCURRENCE_TIME" timestamp(6) without time zone NOT NULL,+
133+ "OCCURRENCE_TIMEtz" timestamp(6) with time zone NOT NULL +
134+ ) +
135+ WITH (orientation=row, compression=no) +
136+ PARTITION BY RANGE (yearweek("OCCURRENCE_TIME")) +
137+ ( +
138+ PARTITION part202549 VALUES LESS THAN (202550), +
139+ PARTITION part202550 VALUES LESS THAN (202551), +
140+ PARTITION part202551 VALUES LESS THAN (202552), +
141+ PARTITION part202552 VALUES LESS THAN (202601), +
142+ PARTITION part202601 VALUES LESS THAN (202602), +
143+ PARTITION part202602 VALUES LESS THAN (202603), +
144+ PARTITION part202650 VALUES LESS THAN (202650) +
145+ ) +
146+ ENABLE ROW MOVEMENT;
147+(1 row)
148+ 
149+insert into person_track_info values (1, 1, '2026-06-01', '2026-06-01');
150+select yearweek(OCCURRENCE_TIME), yearweek(OCCURRENCE_TIMEtz) from person_track_info;
151+ yearweek | yearweek
152+----------+----------
153+ 202622 | 202622
154+(1 row)
155+ 
156+drop table if exists person_track_info;
@@ -9726,6 +9726,63 @@ Datum yearweek_numeric(PG_FUNCTION_ARGS)
9726 PG_RETURN_INT64(year * 100 + week);9726 PG_RETURN_INT64(year * 100 + week);
9727}9727}
9728 9728 
9729+PG_FUNCTION_INFO_V1_PUBLIC(yearweek_timestamp);
9730+extern "C" DLL_PUBLIC Datum yearweek_timestamp(PG_FUNCTION_ARGS);
9731+Datum yearweek_timestamp(PG_FUNCTION_ARGS)
9732+{
9733+ if (PG_ARGISNULL(0)) {
9734+ PG_RETURN_NULL();
9735+ }
9736+ 
9737+ int64 mode = 0;
9738+ if (PG_ARGISNULL(1)) {
9739+ mode = 0;
9740+ } else {
9741+ mode = PG_GETARG_INT64(1);
9742+ }
9743+ int32 week = 0;
9744+ uint year = 0;
9745+ struct pg_tm tm;
9746+ fsec_t fsec;
9747+ Timestamp stamp = PG_GETARG_TIMESTAMP(0);
9748+ if (timestamp2tm(stamp, NULL, &tm, &fsec, NULL, NULL) == 0) {
9749+ week_internal(&tm, &week, mode, &year);
9750+ PG_RETURN_INT64(year * 100 + week);
9751+ } else {
9752+ ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range")));
9753+ PG_RETURN_NULL(); /* suppress the static check */
9754+ }
9755+}
9756+ 
9757+PG_FUNCTION_INFO_V1_PUBLIC(yearweek_timestamptz);
9758+extern "C" DLL_PUBLIC Datum yearweek_timestamptz(PG_FUNCTION_ARGS);
9759+Datum yearweek_timestamptz(PG_FUNCTION_ARGS)
9760+{
9761+ if (PG_ARGISNULL(0)) {
9762+ PG_RETURN_NULL();
9763+ }
9764+ int64 mode = 0;
9765+ if (PG_ARGISNULL(1)) {
9766+ mode = 0;
9767+ } else {
9768+ mode = PG_GETARG_INT64(1);
9769+ }
9770+ uint year = 0;
9771+ int32 week = 0;
9772+ const char* tzn = NULL;
9773+ struct pg_tm tm;
9774+ fsec_t fsec;
9775+ TimestampTz stamp = PG_GETARG_TIMESTAMPTZ(0);
9776+ if (timestamp2tm(stamp, NULL, &tm, &fsec, &tzn, NULL) == 0) {
9777+ week_internal(&tm, &week, mode, &year);
wangfeihuo
wangfeihuowangfeihuo1月26日

image.png

看下要不要像text的函数那样支持mode的参数入参?

likedislike
9778+ PG_RETURN_INT64(year * 100 + week);
9779+ } else {
9780+ ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamptz out of range")));
9781+ PG_RETURN_NULL(); /* suppress the static check */
9782+ }
9783+}
9784+ 
9785+ 
9729/*9786/*
9730 * using timestamp_diff_internal to calculate9787 * using timestamp_diff_internal to calculate
9731 * true if success9788 * true if success
@@ -4,4 +4,9 @@ DROP FUNCTION IF EXISTS pg_catalog.varchar_bytea(varchar);
4DROP VIEW IF EXISTS performance_schema.threads;4DROP VIEW IF EXISTS performance_schema.threads;
5 5 
6DROP FUNCTION IF EXISTS pg_catalog.db_b_format(number, name);6DROP FUNCTION IF EXISTS pg_catalog.db_b_format(number, name);
7-DROP FUNCTION IF EXISTS pg_catalog.db_b_format(unknown, unknown);7+DROP FUNCTION IF EXISTS pg_catalog.db_b_format(unknown, unknown);
8+ 
9+drop function if exists pg_catalog.yearweek(timestamp without time zone);
10+drop function if exists pg_catalog.yearweek(timestamp with time zone);
11+drop function if exists pg_catalog.yearweek(timestamp without time zone, int8);
12+drop function if exists pg_catalog.yearweek(timestamp with time zone, int8);
@@ -52,3 +52,30 @@ drop table t_timestamp5;
52drop table t_timestamp6;52drop table t_timestamp6;
53reset current_schema;53reset current_schema;
54drop schema test_timestampn cascade;54drop schema test_timestampn cascade;
55+ 
56+-- test yearweek with timestamps
57+drop table if exists person_track_info;
58+CREATE TABLE person_track_info (
59+ "ID" "uint8"(20) NOT NULL,
60+ "SOURCE_ID" "uint8"(20),
61+ "OCCURRENCE_TIME" timestamp(6) without time zone NOT NULL,
62+ "OCCURRENCE_TIMEtz" timestamp(6) with time zone NOT NULL
63+)
64+PARTITION BY RANGE ("yearweek"(("OCCURRENCE_TIME")))
65+(
66+ PARTITION "part202549" VALUES LESS THAN ('202550'),
67+ PARTITION "part202550" VALUES LESS THAN ('202551'),
68+ PARTITION "part202551" VALUES LESS THAN ('202552'),
69+ PARTITION "part202552" VALUES LESS THAN ('202601'),
70+ PARTITION "part202601" VALUES LESS THAN ('202602'),
71+ PARTITION "part202602" VALUES LESS THAN ('202603'),
72+ PARTITION "part202650" VALUES LESS THAN ('202650')
73+)
74+ENABLE ROW MOVEMENT;
75+ 
76+select pg_get_tabledef('person_track_info');
77+ 
78+insert into person_track_info values (1, 1, '2026-06-01', '2026-06-01');
79+select yearweek(OCCURRENCE_TIME), yearweek(OCCURRENCE_TIMEtz) from person_track_info;
80+ 
81+drop table if exists person_track_info;
@@ -39,3 +39,8 @@ GRANT SELECT ON performance_schema.threads TO PUBLIC;
39 39 
40CREATE OR REPLACE FUNCTION pg_catalog.db_b_format(number, name) RETURNS text LANGUAGE SQL IMMUTABLE STRICT as 'select db_b_format($1::"any", $2::bigint)';40CREATE OR REPLACE FUNCTION pg_catalog.db_b_format(number, name) RETURNS text LANGUAGE SQL IMMUTABLE STRICT as 'select db_b_format($1::"any", $2::bigint)';
41CREATE OR REPLACE FUNCTION pg_catalog.db_b_format(unknown, unknown) RETURNS text LANGUAGE C IMMUTABLE as '$libdir/dolphin', 'db_b_format_cstring';41CREATE OR REPLACE FUNCTION pg_catalog.db_b_format(unknown, unknown) RETURNS text LANGUAGE C IMMUTABLE as '$libdir/dolphin', 'db_b_format_cstring';
42+ 
43+CREATE OR REPLACE FUNCTION pg_catalog.yearweek(timestamp without time zone, int8) RETURNS int8 LANGUAGE C STABLE CALLED ON NULL INPUT as '$libdir/dolphin', 'yearweek_timestamp';
44+CREATE OR REPLACE FUNCTION pg_catalog.yearweek(timestamp with time zone, int8) RETURNS int8 LANGUAGE C STABLE CALLED ON NULL INPUT as '$libdir/dolphin', 'yearweek_timestamptz';
45+CREATE OR REPLACE FUNCTION pg_catalog.yearweek(timestamp without time zone) RETURNS int8 AS $$ SELECT pg_catalog.yearweek($1, null) $$ LANGUAGE SQL;
46+CREATE OR REPLACE FUNCTION pg_catalog.yearweek(timestamp with time zone) RETURNS int8 AS $$ SELECT pg_catalog.yearweek($1, null) $$ LANGUAGE SQL;