已合并
解决yearweek导入导出报错问题 #2362
laishenghao创建于 1月24日
解决yearweek导入导出报错问题 #2362
已合并
共 5 个文件变更+147-1
| @@ -102,3 +102,55 @@ drop table t_timestamp5; | |||
| 102 | drop table t_timestamp6; | 102 | drop table t_timestamp6; |
| 103 | reset current_schema; | 103 | reset current_schema; |
| 104 | drop schema test_timestampn cascade; | 104 | drop 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); | ||
| 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 calculate | 9787 | * using timestamp_diff_internal to calculate |
| 9731 | * true if success | 9788 | * true if success |
| @@ -4,4 +4,9 @@ DROP FUNCTION IF EXISTS pg_catalog.varchar_bytea(varchar); | |||
| 4 | DROP VIEW IF EXISTS performance_schema.threads; | 4 | DROP VIEW IF EXISTS performance_schema.threads; |
| 5 | 5 | ||
| 6 | DROP FUNCTION IF EXISTS pg_catalog.db_b_format(number, name); | 6 | DROP 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; | |||
| 52 | drop table t_timestamp6; | 52 | drop table t_timestamp6; |
| 53 | reset current_schema; | 53 | reset current_schema; |
| 54 | drop schema test_timestampn cascade; | 54 | drop 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 | ||
| 40 | CREATE 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)'; | 40 | CREATE 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)'; |
| 41 | CREATE OR REPLACE FUNCTION pg_catalog.db_b_format(unknown, unknown) RETURNS text LANGUAGE C IMMUTABLE as '$libdir/dolphin', 'db_b_format_cstring'; | 41 | CREATE 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; | ||
看下要不要像text的函数那样支持mode的参数入参?