|
31 | 31 | #include <utils/builtins.h>
|
32 | 32 | #include <utils/catcache.h>
|
33 | 33 | #include <utils/date.h>
|
| 34 | +#include <utils/elog.h> |
34 | 35 | #include <utils/fmgroids.h>
|
35 | 36 | #include <utils/fmgrprotos.h>
|
36 | 37 | #include <utils/lsyscache.h>
|
|
47 | 48 | #include "jsonb_utils.h"
|
48 | 49 | #include "time_utils.h"
|
49 | 50 | #include "utils.h"
|
| 51 | +#include "uuid.h" |
| 52 | +#include <utils/timestamp.h> |
| 53 | +#include <utils/uuid.h> |
50 | 54 |
|
51 | 55 | typedef struct
|
52 | 56 | {
|
@@ -148,7 +152,7 @@ ts_time_value_to_internal(Datum time_val, Oid type_oid)
|
148 | 152 | elog(ERROR, "unknown time type \"%s\"", format_type_be(type_oid));
|
149 | 153 | }
|
150 | 154 |
|
151 |
| - if (IS_INTEGER_TYPE(type_oid)) |
| 155 | + if (IS_INTEGER_TYPE(type_oid) || IS_UUID_TYPE(type_oid)) |
152 | 156 | {
|
153 | 157 | /* Integer time types have no distinction between min, max and
|
154 | 158 | * infinity. We don't want min and max to be turned into infinity for
|
@@ -189,6 +193,30 @@ ts_time_value_to_internal(Datum time_val, Oid type_oid)
|
189 | 193 | res = DirectFunctionCall1(ts_pg_timestamp_to_unix_microseconds, tz);
|
190 | 194 |
|
191 | 195 | return DatumGetInt64(res);
|
| 196 | + case UUIDOID: |
| 197 | + { |
| 198 | + uint64 unixtime_ms = 0; |
| 199 | + |
| 200 | + /* |
| 201 | + * Extract the unix timestamp from the UUUID. Note that we cannot |
| 202 | + * use the (optional) sub-milliseconds part because there is no |
| 203 | + * way to know whether it represents time or is random. |
| 204 | + * |
| 205 | + * If the UUID is not v7, error out. |
| 206 | + */ |
| 207 | + if (!ts_uuid_v7_extract_unixtime(DatumGetUUIDP(time_val), &unixtime_ms, NULL)) |
| 208 | + { |
| 209 | + ereport(ERROR, |
| 210 | + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 211 | + errmsg("%s is not version 7 UUID", |
| 212 | + DatumGetCString(DirectFunctionCall1(uuid_out, time_val))), |
| 213 | + errdetail( |
| 214 | + "UUID \"time\" partitioning columns only support version 7 UUIDs.")); |
| 215 | + } |
| 216 | + |
| 217 | + /* Convert to microseconds */ |
| 218 | + return unixtime_ms * 1000; |
| 219 | + } |
192 | 220 | default:
|
193 | 221 | elog(ERROR, "unknown time type \"%s\"", format_type_be(type_oid));
|
194 | 222 | return -1;
|
@@ -294,6 +322,30 @@ ts_time_value_to_internal_or_infinite(Datum time_val, Oid type_oid)
|
294 | 322 |
|
295 | 323 | return ts_time_value_to_internal(time_val, type_oid);
|
296 | 324 | }
|
| 325 | + case UUIDOID: |
| 326 | + { |
| 327 | + uint64 unixtime_ms = 0; |
| 328 | + |
| 329 | + /* |
| 330 | + * Extract the unix timestamp from the UUUID. Note that we cannot |
| 331 | + * use the (optional) sub-milliseconds part because there is no |
| 332 | + * way to know whether it represents time or is random. |
| 333 | + * |
| 334 | + * If the UUID is not v7, error out. |
| 335 | + */ |
| 336 | + if (!ts_uuid_v7_extract_unixtime(DatumGetUUIDP(time_val), &unixtime_ms, NULL)) |
| 337 | + { |
| 338 | + ereport(ERROR, |
| 339 | + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 340 | + errmsg("%s is not version 7 UUID", |
| 341 | + DatumGetCString(DirectFunctionCall1(uuid_out, time_val))), |
| 342 | + errdetail( |
| 343 | + "UUID \"time\" partitioning columns only support version 7 UUIDs.")); |
| 344 | + } |
| 345 | + |
| 346 | + /* Convert to microseconds */ |
| 347 | + return unixtime_ms * 1000; |
| 348 | + } |
297 | 349 | default:
|
298 | 350 | return ts_time_value_to_internal(time_val, type_oid);
|
299 | 351 | }
|
@@ -338,6 +390,17 @@ ts_internal_to_time_value(int64 value, Oid type)
|
338 | 390 | return DirectFunctionCall1(ts_pg_unix_microseconds_to_timestamp, Int64GetDatum(value));
|
339 | 391 | case DATEOID:
|
340 | 392 | return DirectFunctionCall1(ts_pg_unix_microseconds_to_date, Int64GetDatum(value));
|
| 393 | + case UUIDOID: |
| 394 | + { |
| 395 | + /* |
| 396 | + * Convert the internal unixtime in ms to a UUID with the |
| 397 | + * non-timestamp bits set to zero. We do not set the version |
| 398 | + * either, because for ranges we only care about the prefix in |
| 399 | + * order to divide the whole UUID space into a set of slices. |
| 400 | + */ |
| 401 | + const pg_uuid_t *uuid = ts_create_uuid_v7_from_unixtime_us(value, true, false); |
| 402 | + return UUIDPGetDatum(uuid); |
| 403 | + } |
341 | 404 | default:
|
342 | 405 | if (ts_type_is_int8_binary_compatible(type))
|
343 | 406 | return Int64GetDatum(value);
|
@@ -365,6 +428,7 @@ ts_internal_to_time_int64(int64 value, Oid type)
|
365 | 428 | return value;
|
366 | 429 | case TIMESTAMPOID:
|
367 | 430 | case TIMESTAMPTZOID:
|
| 431 | + case UUIDOID: |
368 | 432 | /* we continue ts_time_value_to_internal's incorrect handling of TIMESTAMPs for
|
369 | 433 | * compatibility */
|
370 | 434 | return DatumGetInt64(
|
|
0 commit comments