|
1 | | -/*───────────────────────────────────────────────────────────────────────────── |
2 | | - typeid 0.1.0 → 0.2.0 upgrade |
3 | | - * preserves camel-case TypeID identifier * |
4 | | -─────────────────────────────────────────────────────────────────────────────*/ |
5 | | -BEGIN; |
| 1 | +/* |
| 2 | + typeid v0.1.0 -> v0.2.0 |
| 3 | + This script handles the following changes: |
| 4 | + 1. Drops the old `min`/`max` aggregates which are incompatible with the new library. |
| 5 | + 2. Drops the old state functions for those aggregates. |
| 6 | + 3. Creates new state and combine functions for parallel-safe `min`/`max` aggregates. |
| 7 | + 4. Creates the new parallel-safe `min`/`max` aggregates. |
| 8 | + 5. Adds binary `SEND`/`RECEIVE` functions to the `TypeID` type for replication. |
| 9 | + 6. Adds all new v0.2.0 utility functions (`typeid_prefix`, `typeid_is_valid`, etc.). |
| 10 | + 7. Adds the new `@>` prefix-matching operator. |
| 11 | + 8. Adds an implicit `CAST` from `text` to `typeid`. |
| 12 | + 9. Marks all existing functions as `IMMUTABLE` and `PARALLEL SAFE`. |
| 13 | + 10. Adds comments to the new functions and operators. |
| 14 | +*/ |
| 15 | + |
| 16 | +-- Step 1: Drop old aggregates and their functions from v0.1.0 |
| 17 | +DROP AGGREGATE IF EXISTS min(TypeID); |
| 18 | +DROP AGGREGATE IF EXISTS max(TypeID); |
| 19 | +DROP FUNCTION IF EXISTS type_id_min_state(TypeID, TypeID); |
| 20 | +DROP FUNCTION IF EXISTS type_id_max_state(TypeID, TypeID); |
| 21 | + |
| 22 | +-- Step 2: Create new functions for v0.2.0 |
6 | 23 |
|
7 | | --- 1 ── binary protocol ------------------------------------------------------- |
| 24 | +-- Binary protocol functions |
8 | 25 | CREATE FUNCTION typeid_recv(internal) |
9 | | -RETURNS TypeID |
10 | | -IMMUTABLE STRICT PARALLEL SAFE |
11 | | -LANGUAGE c |
12 | | -AS 'MODULE_PATHNAME', 'typeid_recv_wrapper'; |
| 26 | +RETURNS TypeID IMMUTABLE STRICT PARALLEL SAFE |
| 27 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_recv_wrapper'; |
13 | 28 |
|
14 | 29 | CREATE FUNCTION typeid_send(TypeID) |
15 | | -RETURNS bytea |
16 | | -IMMUTABLE STRICT PARALLEL SAFE |
17 | | -LANGUAGE c |
18 | | -AS 'MODULE_PATHNAME', 'typeid_send_wrapper'; |
19 | | - |
20 | | -ALTER TYPE TypeID |
21 | | - SET (RECEIVE = typeid_recv, SEND = typeid_send); |
22 | | - |
23 | | --- 2 ── helper: prefix as text ------------------------------------------------ |
24 | | -CREATE FUNCTION typeid_prefix("typeid" TypeID) |
25 | | -RETURNS text |
26 | | -IMMUTABLE STRICT PARALLEL SAFE |
27 | | -LANGUAGE c |
28 | | -AS 'MODULE_PATHNAME', 'typeid_prefix_wrapper'; |
29 | | - |
30 | | --- 3 ── implicit cast text → TypeID ----------------------------------------- |
31 | | -CREATE CAST (text AS TypeID) |
32 | | - WITH INOUT |
33 | | - AS IMPLICIT; |
34 | | - |
35 | | --- 4 ── parallel-safe aggregates --------------------------------------------- |
36 | | -CREATE FUNCTION type_id_min_type_id_min_combine(this TypeID, v TypeID) |
37 | | -RETURNS TypeID |
38 | | -LANGUAGE c |
39 | | -AS 'MODULE_PATHNAME', 'type_id_min_type_id_min_combine_wrapper'; |
| 30 | +RETURNS bytea IMMUTABLE STRICT PARALLEL SAFE |
| 31 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_send_wrapper'; |
40 | 32 |
|
41 | | -CREATE FUNCTION type_id_max_type_id_max_combine(this TypeID, v TypeID) |
42 | | -RETURNS TypeID |
43 | | -LANGUAGE c |
44 | | -AS 'MODULE_PATHNAME', 'type_id_max_type_id_max_combine_wrapper'; |
| 33 | +-- New utility functions |
| 34 | +CREATE FUNCTION typeid_prefix(typeid TypeID) |
| 35 | +RETURNS TEXT IMMUTABLE STRICT PARALLEL SAFE |
| 36 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_prefix_wrapper'; |
45 | 37 |
|
46 | | -DROP AGGREGATE IF EXISTS min(TypeID); |
47 | | -CREATE AGGREGATE min (TypeID) |
48 | | -( |
49 | | - SFUNC = type_id_min_type_id_min_state, |
50 | | - STYPE = TypeID, |
51 | | - COMBINEFUNC = type_id_min_type_id_min_combine, |
52 | | - PARALLEL = SAFE |
| 38 | +CREATE FUNCTION typeid_generate_nil() |
| 39 | +RETURNS TypeID STRICT VOLATILE PARALLEL SAFE |
| 40 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_generate_nil_wrapper'; |
| 41 | + |
| 42 | +CREATE FUNCTION typeid_is_valid(input TEXT) |
| 43 | +RETURNS bool IMMUTABLE STRICT PARALLEL SAFE |
| 44 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_is_valid_wrapper'; |
| 45 | + |
| 46 | +CREATE FUNCTION typeid_has_prefix(typeid TypeID, prefix TEXT) |
| 47 | +RETURNS bool IMMUTABLE STRICT PARALLEL SAFE |
| 48 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_has_prefix_wrapper'; |
| 49 | + |
| 50 | +CREATE FUNCTION typeid_is_nil_prefix(typeid TypeID) |
| 51 | +RETURNS bool IMMUTABLE STRICT PARALLEL SAFE |
| 52 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_is_nil_prefix_wrapper'; |
| 53 | + |
| 54 | +CREATE FUNCTION typeid_generate_batch(prefix TEXT, count INT) |
| 55 | +RETURNS TypeID[] STRICT VOLATILE PARALLEL SAFE |
| 56 | +LANGUAGE c AS 'MODULE_PATHNAME', 'typeid_generate_batch_wrapper'; |
| 57 | + |
| 58 | +-- New aggregate helper functions |
| 59 | +CREATE FUNCTION "type_id_max_type_id_max_combine"( |
| 60 | + "this" TypeID, |
| 61 | + "v" TypeID |
| 62 | +) RETURNS TypeID |
| 63 | +LANGUAGE c AS 'MODULE_PATHNAME', 'type_id_max_type_id_max_combine_wrapper'; |
| 64 | + |
| 65 | +CREATE FUNCTION "type_id_max_type_id_max_state"( |
| 66 | + "this" TypeID, |
| 67 | + "arg_one" TypeID |
| 68 | +) RETURNS TypeID |
| 69 | +LANGUAGE c AS 'MODULE_PATHNAME', 'type_id_max_type_id_max_state_wrapper'; |
| 70 | + |
| 71 | +CREATE FUNCTION "type_id_min_type_id_min_combine"( |
| 72 | + "this" TypeID, |
| 73 | + "v" TypeID |
| 74 | +) RETURNS TypeID |
| 75 | +LANGUAGE c AS 'MODULE_PATHNAME', 'type_id_min_type_id_min_combine_wrapper'; |
| 76 | + |
| 77 | +CREATE FUNCTION "type_id_min_type_id_min_state"( |
| 78 | + "this" TypeID, |
| 79 | + "arg_one" TypeID |
| 80 | +) RETURNS TypeID |
| 81 | +LANGUAGE c AS 'MODULE_PATHNAME', 'type_id_min_type_id_min_state_wrapper'; |
| 82 | + |
| 83 | + |
| 84 | +-- Step 3: Update the TypeID type definition |
| 85 | +ALTER TYPE TypeID SET (RECEIVE = typeid_recv, SEND = typeid_send); |
| 86 | + |
| 87 | +-- Step 4: Re-create aggregates with new parallel-safe functions |
| 88 | +CREATE AGGREGATE max (TypeID) ( |
| 89 | + SFUNC = "type_id_max_type_id_max_state", |
| 90 | + STYPE = TypeID, |
| 91 | + COMBINEFUNC = "type_id_max_type_id_max_combine", |
| 92 | + PARALLEL = SAFE |
53 | 93 | ); |
54 | 94 |
|
55 | | -DROP AGGREGATE IF EXISTS max(TypeID); |
56 | | -CREATE AGGREGATE max (TypeID) |
57 | | -( |
58 | | - SFUNC = type_id_max_type_id_max_state, |
59 | | - STYPE = TypeID, |
60 | | - COMBINEFUNC = type_id_max_type_id_max_combine, |
61 | | - PARALLEL = SAFE |
| 95 | +CREATE AGGREGATE min (TypeID) ( |
| 96 | + SFUNC = "type_id_min_type_id_min_state", |
| 97 | + STYPE = TypeID, |
| 98 | + COMBINEFUNC = "type_id_min_type_id_min_combine", |
| 99 | + PARALLEL = SAFE |
62 | 100 | ); |
63 | 101 |
|
64 | | --- 5 ── mark helpers IMMUTABLE & PARALLEL SAFE -------------------------------- |
65 | | -ALTER FUNCTION typeid_cmp(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
66 | | -ALTER FUNCTION typeid_lt(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
67 | | -ALTER FUNCTION typeid_le(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
68 | | -ALTER FUNCTION typeid_eq(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
69 | | -ALTER FUNCTION typeid_ge(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
70 | | -ALTER FUNCTION typeid_gt(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
71 | | -ALTER FUNCTION typeid_ne(TypeID,TypeID) IMMUTABLE PARALLEL SAFE; |
72 | | -ALTER FUNCTION typeid_hash(TypeID) IMMUTABLE PARALLEL SAFE; |
73 | | -ALTER FUNCTION typeid_hash_extended(TypeID,bigint) IMMUTABLE PARALLEL SAFE; |
74 | | -ALTER FUNCTION uuid_to_typeid(text,uuid) IMMUTABLE PARALLEL SAFE; |
75 | | -ALTER FUNCTION typeid_to_uuid(TypeID) IMMUTABLE PARALLEL SAFE; |
76 | | - |
77 | | --- 6 ── NEW v0.2.0 utility functions ------------------------------------------ |
78 | | - |
79 | | --- Generate TypeID with empty prefix (UUID-only format) |
80 | | -CREATE FUNCTION typeid_generate_nil() |
81 | | -RETURNS TypeID |
82 | | -STRICT VOLATILE PARALLEL SAFE |
83 | | -LANGUAGE c |
84 | | -AS 'MODULE_PATHNAME', 'typeid_generate_nil_wrapper'; |
85 | | - |
86 | | --- Validate TypeID format without parsing |
87 | | -CREATE FUNCTION typeid_is_valid("input" TEXT) |
88 | | -RETURNS bool |
89 | | -IMMUTABLE STRICT PARALLEL SAFE |
90 | | -LANGUAGE c |
91 | | -AS 'MODULE_PATHNAME', 'typeid_is_valid_wrapper'; |
92 | | - |
93 | | --- Check if TypeID has a specific prefix |
94 | | -CREATE FUNCTION typeid_has_prefix("typeid" TypeID, "prefix" TEXT) |
95 | | -RETURNS bool |
96 | | -IMMUTABLE STRICT PARALLEL SAFE |
97 | | -LANGUAGE c |
98 | | -AS 'MODULE_PATHNAME', 'typeid_has_prefix_wrapper'; |
99 | | - |
100 | | --- Check if TypeID has empty prefix |
101 | | -CREATE FUNCTION typeid_is_nil_prefix("typeid" TypeID) |
102 | | -RETURNS bool |
103 | | -IMMUTABLE STRICT PARALLEL SAFE |
104 | | -LANGUAGE c |
105 | | -AS 'MODULE_PATHNAME', 'typeid_is_nil_prefix_wrapper'; |
106 | | - |
107 | | - |
108 | | - |
109 | | --- Generate multiple TypeIDs efficiently |
110 | | -CREATE FUNCTION typeid_generate_batch("prefix" TEXT, "count" INT) |
111 | | -RETURNS TypeID[] |
112 | | -STRICT VOLATILE PARALLEL SAFE |
113 | | -LANGUAGE c |
114 | | -AS 'MODULE_PATHNAME', 'typeid_generate_batch_wrapper'; |
115 | | - |
116 | | --- 7 ── NEW v0.2.0 operators and documentation -------------------------------- |
117 | | - |
118 | | --- Create prefix matching operator (follows PostgreSQL "contains" semantics) |
| 102 | +-- Step 5: Update existing functions to be parallel safe |
| 103 | +ALTER FUNCTION typeid_in(cstring) IMMUTABLE PARALLEL SAFE; |
| 104 | +ALTER FUNCTION typeid_out(TypeID) IMMUTABLE PARALLEL SAFE; |
| 105 | +ALTER FUNCTION typeid_generate(TEXT) VOLATILE PARALLEL SAFE; |
| 106 | +ALTER FUNCTION uuid_to_typeid(TEXT, uuid) IMMUTABLE PARALLEL SAFE; |
| 107 | +ALTER FUNCTION typeid_to_uuid(TypeID) IMMUTABLE PARALLEL SAFE; |
| 108 | +ALTER FUNCTION typeid_cmp(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 109 | +ALTER FUNCTION typeid_lt(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 110 | +ALTER FUNCTION typeid_le(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 111 | +ALTER FUNCTION typeid_eq(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 112 | +ALTER FUNCTION typeid_ge(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 113 | +ALTER FUNCTION typeid_gt(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 114 | +ALTER FUNCTION typeid_ne(TypeID, TypeID) IMMUTABLE PARALLEL SAFE; |
| 115 | +ALTER FUNCTION typeid_hash(TypeID) IMMUTABLE PARALLEL SAFE; |
| 116 | +ALTER FUNCTION typeid_hash_extended(TypeID, bigint) IMMUTABLE PARALLEL SAFE; |
| 117 | + |
| 118 | + |
| 119 | +-- Step 6: Create new operators and casts |
| 120 | +CREATE CAST (text AS TypeID) |
| 121 | +WITH INOUT AS IMPLICIT; |
| 122 | + |
119 | 123 | CREATE OPERATOR @> ( |
120 | 124 | LEFTARG = typeid, |
121 | 125 | RIGHTARG = text, |
122 | | - PROCEDURE = typeid_has_prefix, |
123 | | - COMMUTATOR = '@<' |
| 126 | + PROCEDURE = typeid_has_prefix |
124 | 127 | ); |
125 | 128 |
|
126 | | --- Add function documentation |
127 | | -COMMENT ON FUNCTION typeid_prefix(typeid) IS 'Extract the prefix from a TypeID for indexing and filtering'; |
128 | | -COMMENT ON FUNCTION typeid_has_prefix(typeid, text) IS 'Check if TypeID has a specific prefix - useful for filtering'; |
129 | | -COMMENT ON FUNCTION typeid_is_valid(text) IS 'Validate TypeID format without parsing - useful for constraints'; |
130 | | -COMMENT ON FUNCTION typeid_generate_nil() IS 'Generate TypeID with empty prefix (UUID-only format)'; |
131 | | -COMMENT ON FUNCTION typeid_generate_batch(text, int) IS 'Generate multiple TypeIDs with the same prefix efficiently'; |
132 | | - |
133 | | -COMMIT; |
| 129 | +-- Step 7: Add comments for new objects |
| 130 | +COMMENT ON FUNCTION typeid_prefix(typeid) IS 'Extract the prefix from a TypeID for indexing and filtering.'; |
| 131 | +COMMENT ON FUNCTION typeid_has_prefix(typeid, text) IS 'Check if a TypeID has a specific prefix.'; |
| 132 | +COMMENT ON FUNCTION typeid_is_valid(text) IS 'Validate if a string is a valid TypeID representation.'; |
| 133 | +COMMENT ON FUNCTION typeid_generate_nil() IS 'Generate a TypeID with an empty prefix.'; |
| 134 | +COMMENT ON FUNCTION typeid_generate_batch(text, int) IS 'Generate a batch of TypeIDs with the same prefix.'; |
| 135 | +COMMENT ON OPERATOR @>(typeid, text) IS 'Does the TypeID have the specified prefix?'; |
0 commit comments