Skip to content

Commit c89356f

Browse files
authored
Merge pull request #170 from cipherstash/refactor/canonical-config
Canonical shared encryption config
2 parents b3ed231 + c40537d commit c89356f

6 files changed

Lines changed: 292 additions & 20 deletions

File tree

.github/workflows/release-eql.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ on:
1212
# Useful for debugging
1313
workflow_dispatch:
1414

15+
env:
16+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
17+
MISE_VERBOSE: "1"
18+
1519
defaults:
1620
run:
1721
shell: bash -l {0}
@@ -29,9 +33,9 @@ jobs:
2933
steps:
3034
- uses: actions/checkout@v4
3135

32-
- uses: jdx/mise-action@v2
36+
- uses: jdx/mise-action@v3
3337
with:
34-
version: 2025.1.6 # [default: latest] mise version to install
38+
version: 2026.4.0 # [default: latest] mise version to install
3539
install: true # [default: true] run `mise install`
3640
cache: true # [default: true] cache mise using GitHub's cache
3741

@@ -76,9 +80,9 @@ jobs:
7680
steps:
7781
- uses: actions/checkout@v4
7882

79-
- uses: jdx/mise-action@v2
83+
- uses: jdx/mise-action@v3
8084
with:
81-
version: 2025.1.6 # [default: latest] mise version to install
85+
version: 2026.4.0 # [default: latest] mise version to install
8286
install: true # [default: true] run `mise install`
8387
cache: true # [default: true] cache mise using GitHub's cache
8488

.github/workflows/test-eql.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ on:
2121

2222
workflow_dispatch:
2323

24+
env:
25+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
26+
MISE_VERBOSE: "1"
27+
2428
defaults:
2529
run:
2630
shell: bash -l {0}

docs/reference/index-config.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,22 @@ SELECT eql_v2.add_search_config(
3535

3636
#### Option (`cast_as`)
3737

38+
The type field can be specified as either `plaintext_type` (preferred) or `cast_as` (deprecated alias retained for backwards compatibility).
39+
When both are present, `plaintext_type` takes precedence.
40+
3841
Supported types:
3942

4043
- `text`
4144
- `int`
4245
- `small_int`
4346
- `big_int`
44-
- `real`
47+
- `real` (also accepts `float`)
4548
- `double`
4649
- `boolean`
4750
- `date`
48-
- `jsonb`
51+
- `json` (also accepts `jsonb`)
52+
- `decimal`
53+
- `timestamp`
4954

5055
#### Options for match indexes (`opts`)
5156

src/config/constraints.sql

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,40 @@ $$ LANGUAGE plpgsql;
6161
--! @brief Validate cast types in configuration
6262
--! @internal
6363
--!
64-
--! Checks that all 'cast_as' types specified in the configuration are valid.
65-
--! Valid cast types are: text, int, small_int, big_int, real, double, boolean, date, jsonb.
64+
--! Checks that all 'cast_as' and 'plaintext_type' types specified in the configuration are valid.
65+
--! Valid cast types are: text, int, small_int, big_int, real, double, boolean, date, jsonb, json, float, decimal, timestamp.
6666
--!
6767
--! @param jsonb Configuration data to validate
6868
--! @return boolean True if all cast types are valid or no cast types specified
6969
--! @throws Exception if any invalid cast type found
7070
--!
7171
--! @note Used in CHECK constraint on eql_v2_configuration table
72-
--! @note Empty configurations (no cast_as fields) are valid
72+
--! @note Empty configurations (no cast_as/plaintext_type fields) are valid
7373
--! @note Cast type names are EQL's internal representations, not PostgreSQL native types
74+
--! @note 'plaintext_type' is accepted as a canonical alias for 'cast_as'
7475
CREATE FUNCTION eql_v2.config_check_cast(val jsonb)
7576
RETURNS BOOLEAN
77+
IMMUTABLE STRICT PARALLEL SAFE
7678
AS $$
79+
DECLARE
80+
_valid_types text[] := '{text, int, small_int, big_int, real, double, boolean, date, jsonb, json, float, decimal, timestamp}';
7781
BEGIN
78-
-- If there are cast_as fields, validate them
82+
-- Validate cast_as fields
7983
IF EXISTS (SELECT jsonb_array_elements_text(jsonb_path_query_array(val, '$.tables.*.*.cast_as'))) THEN
80-
IF (SELECT bool_and(cast_as = ANY('{text, int, small_int, big_int, real, double, boolean, date, jsonb}'))
84+
IF NOT (SELECT bool_and(cast_as = ANY(_valid_types))
8185
FROM (SELECT jsonb_array_elements_text(jsonb_path_query_array(val, '$.tables.*.*.cast_as')) AS cast_as) casts) THEN
82-
RETURN true;
86+
RAISE 'Configuration has an invalid cast_as (%). Cast should be one of %', val, _valid_types;
87+
END IF;
88+
END IF;
89+
90+
-- Validate plaintext_type fields (canonical alias for cast_as)
91+
IF EXISTS (SELECT jsonb_array_elements_text(jsonb_path_query_array(val, '$.tables.*.*.plaintext_type'))) THEN
92+
IF NOT (SELECT bool_and(pt = ANY(_valid_types))
93+
FROM (SELECT jsonb_array_elements_text(jsonb_path_query_array(val, '$.tables.*.*.plaintext_type')) AS pt) types) THEN
94+
RAISE 'Configuration has an invalid plaintext_type (%). Type should be one of %', val, _valid_types;
8395
END IF;
84-
RAISE 'Configuration has an invalid cast_as (%). Cast should be one of {text, int, small_int, big_int, real, double, boolean, date, jsonb}', val;
8596
END IF;
86-
-- If no cast_as fields exist (empty config), that's valid
97+
8798
RETURN true;
8899
END;
89100
$$ LANGUAGE plpgsql;

src/config/functions.sql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ AS $$
4646
RAISE EXCEPTION '% index exists for column: % %', index_name, table_name, column_name;
4747
END IF;
4848

49-
IF NOT cast_as = ANY('{text, int, small_int, big_int, real, double, boolean, date, jsonb}') THEN
49+
IF NOT cast_as = ANY('{text, int, small_int, big_int, real, double, boolean, date, jsonb, json, float, decimal, timestamp}') THEN
5050
RAISE EXCEPTION '% is not a valid cast type', cast_as;
5151
END IF;
5252

@@ -470,16 +470,16 @@ AS $$
470470
BEGIN
471471
RETURN QUERY
472472
WITH tables AS (
473-
SELECT config.state, tables.key AS table, tables.value AS config
474-
FROM public.eql_v2_configuration config, jsonb_each(data->'tables') tables
475-
WHERE config.data->>'v' = '1'
473+
SELECT cfg.state, tables.key AS table, tables.value AS tbl_config
474+
FROM public.eql_v2_configuration cfg, jsonb_each(data->'tables') tables
475+
WHERE cfg.data->>'v' = '1'
476476
)
477477
SELECT
478478
tables.state,
479479
tables.table,
480480
column_config.key,
481-
column_config.value->>'cast_as',
481+
COALESCE(column_config.value->>'plaintext_type', column_config.value->>'cast_as'),
482482
column_config.value->'indexes'
483-
FROM tables, jsonb_each(tables.config) column_config;
483+
FROM tables, jsonb_each(tables.tbl_config) column_config;
484484
END;
485485
$$ LANGUAGE plpgsql;

0 commit comments

Comments
 (0)