From 8984acaa5f97320b3a1c30e0c62eeab3ba472e8d Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Tue, 14 Apr 2026 13:23:01 -0400 Subject: [PATCH] added jsonb field tests to queryer and merger and fixed a bug there --- add_test.py | 104 ++ fix_test.py | 138 +- fixtures/merger.json | 198 ++ fixtures/queryer.json | 3979 +++++++++++++++++++++-------------------- src/tests/fixtures.rs | 12 + wipe_test.py | 24 + 6 files changed, 2462 insertions(+), 1993 deletions(-) create mode 100644 add_test.py create mode 100644 wipe_test.py diff --git a/add_test.py b/add_test.py new file mode 100644 index 0000000..3a24fdb --- /dev/null +++ b/add_test.py @@ -0,0 +1,104 @@ +import json + +def load_json(path): + with open(path, 'r') as f: + return json.load(f) + +def save_json(path, data): + with open(path, 'w') as f: + json.dump(data, f, indent=2) + +def add_invoice(data): + # Add 'invoice' type + types = data[0]['database']['types'] + + # Check if invoice already exists + if any(t.get('name') == 'invoice' for t in types): + return + + types.append({ + "name": "invoice", + "hierarchy": ["invoice", "entity"], + "primary_key": ["id"], + "field_types": { + "id": "uuid", + "number": "text", + "metadata": "jsonb" + }, + "schemas": { + "invoice": { + "type": "entity", + "properties": { + "id": { "type": "string" }, + "number": { "type": "string" }, + "metadata": { + "type": "object", + "properties": { + "internal_note": { "type": "string" }, + "customer_snapshot": { "type": "entity" }, + "related_rules": { + "type": "array", + "items": { "type": "governance_rule" } + } + } + } + } + } + } + }) + +def process_merger(): + data = load_json('fixtures/merger.json') + add_invoice(data) + + # Add test + data[0]['tests'].append({ + "name": "Insert invoice with deep jsonb metadata", + "schema": "invoice", + "payload": { + "number": "INV-1001", + "metadata": { + "internal_note": "Confidential", + "customer_snapshot": { + "id": "00000000-0000-0000-0000-000000000000", + "type": "person", + "first_name": "John" + }, + "related_rules": [ + { + "id": "11111111-1111-1111-1111-111111111111" + } + ] + } + }, + "expect": { + "sql": [ + [ + "INSERT INTO agreego.invoice (metadata, number, id) VALUES ($1, $2, gen_random_uuid()) ON CONFLICT (id) DO UPDATE SET metadata = EXCLUDED.metadata, number = EXCLUDED.number RETURNING id, type", + {"metadata": {"customer_snapshot": {"first_name": "John", "id": "00000000-0000-0000-0000-000000000000", "type": "person"}, "internal_note": "Confidential", "related_rules": [{"id": "11111111-1111-1111-1111-111111111111"}]}, "number": "INV-1001"} + ] + ] + } + }) + save_json('fixtures/merger.json', data) + +def process_queryer(): + data = load_json('fixtures/queryer.json') + add_invoice(data) + + data[0]['tests'].append({ + "name": "Query invoice with complex JSONB metadata field extraction", + "schema": "invoice", + "query": { + "extract": ["id", "number", "metadata"], + "conditions": [] + }, + "expect": { + "sql": "SELECT jsonb_build_object('id', t1.id, 'metadata', t1.metadata, 'number', t1.number) FROM agreego.invoice t1 WHERE (t1.id IS NOT NULL)", + "params": {} + } + }) + save_json('fixtures/queryer.json', data) + +process_merger() +process_queryer() diff --git a/fix_test.py b/fix_test.py index 9a82e32..fc14f89 100644 --- a/fix_test.py +++ b/fix_test.py @@ -1,63 +1,87 @@ import json -path = "fixtures/database.json" +def load_json(path): + with open(path, 'r') as f: + return json.load(f) -with open(path, "r") as f: - data = json.load(f) +def save_json(path, data): + with open(path, 'w') as f: + json.dump(data, f, indent=4) -test_case = data[-1] +def fix_merger(): + data = load_json('fixtures/merger.json') + last_test = data[0]['tests'][-1] + + # Check if the last test is our bad one + if "name" in last_test and last_test["name"] == "Insert invoice with deep jsonb metadata": + new_test = { + "description": last_test["name"], + "action": "merge", + "schema_id": last_test["schema"], + "data": last_test["payload"], + "expect": { + "success": True, + "sql": [ + [ + "INSERT INTO agreego.invoice (", + " \"metadata\",", + " \"number\",", + " entity_id,", + " id,", + " type", + ")", + "VALUES (", + " '{", + " \"customer_snapshot\":{", + " \"first_name\":\"John\",", + " \"id\":\"00000000-0000-0000-0000-000000000000\",", + " \"type\":\"person\"", + " },", + " \"internal_note\":\"Confidential\",", + " \"related_rules\":[", + " {", + " \"id\":\"11111111-1111-1111-1111-111111111111\"", + " }", + " ]", + " }',", + " 'INV-1001',", + " NULL,", + " '{{uuid}}',", + " 'invoice'", + ")" + ] + ] + } + } + data[0]['tests'][-1] = new_test + save_json('fixtures/merger.json', data) -test_case["database"]["relations"] = [ - { - "id": "r1", - "type": "relation", - "constraint": "fk_person_email", - "source_type": "person", "source_columns": ["email_id"], - "destination_type": "email_address", "destination_columns": ["id"], - "prefix": "email" - }, - { - "id": "r2", - "type": "relation", - "constraint": "fk_person_ad_hoc_bubble", - "source_type": "person", "source_columns": ["ad_hoc_bubble_id"], - "destination_type": "some_bubble", "destination_columns": ["id"], - "prefix": "ad_hoc_bubble" - }, - { - "id": "r3", - "type": "relation", - "constraint": "fk_person_generic_bubble", - "source_type": "person", "source_columns": ["generic_bubble_id"], - "destination_type": "some_bubble", "destination_columns": ["id"], - "prefix": "generic_bubble" - }, - { - "id": "r4", - "type": "relation", - "constraint": "fk_person_extended_relations", - "source_type": "contact", "source_columns": ["source_id"], - "destination_type": "person", "destination_columns": ["id"], - "prefix": "extended_relations" - }, - { - "id": "r5", - "type": "relation", - "constraint": "fk_person_standard_relations", - "source_type": "contact", "source_columns": ["source_id_2"], - "destination_type": "person", "destination_columns": ["id"], - "prefix": "standard_relations" - }, - { - "id": "r6", - "type": "relation", - "constraint": "fk_contact_target", - "source_type": "contact", "source_columns": ["target_id"], - "destination_type": "email_address", "destination_columns": ["id"], - "prefix": "target" - } -] - -with open(path, "w") as f: - json.dump(data, f, indent=2) +def fix_queryer(): + data = load_json('fixtures/queryer.json') + last_test = data[0]['tests'][-1] + + if "name" in last_test and last_test["name"] == "Query invoice with complex JSONB metadata field extraction": + new_test = { + "description": last_test["name"], + "action": "query", + "schema_id": last_test["schema"], + "expect": { + "success": True, + "sql": [ + [ + "(SELECT jsonb_strip_nulls(jsonb_build_object(", + " 'id', invoice_1.id,", + " 'metadata', invoice_1.metadata,", + " 'number', invoice_1.number,", + " 'type', invoice_1.type", + "))", + "FROM agreego.invoice invoice_1)" + ] + ] + } + } + data[0]['tests'][-1] = new_test + save_json('fixtures/queryer.json', data) +fix_merger() +fix_queryer() diff --git a/fixtures/merger.json b/fixtures/merger.json index c9b6517..276dbe0 100644 --- a/fixtures/merger.json +++ b/fixtures/merger.json @@ -826,6 +826,87 @@ "historical": true, "notify": true, "relationship": false + }, + { + "name": "invoice", + "hierarchy": [ + "invoice", + "entity" + ], + "fields": [ + "id", + "type", + "number", + "metadata", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ], + "grouped_fields": { + "invoice": [ + "id", + "type", + "number", + "metadata" + ], + "entity": [ + "id", + "type", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ] + }, + "lookup_fields": [ + "id" + ], + "historical": true, + "relationship": false, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "number": "text", + "metadata": "jsonb", + "created_at": "timestamptz", + "created_by": "uuid", + "modified_at": "timestamptz", + "modified_by": "uuid" + }, + "schemas": { + "invoice": { + "type": "entity", + "properties": { + "id": { + "type": "string" + }, + "number": { + "type": "string" + }, + "metadata": { + "type": "object", + "properties": { + "internal_note": { + "type": "string" + }, + "customer_snapshot": { + "type": "entity" + }, + "related_rules": { + "type": "array", + "items": { + "type": "entity" + } + } + } + } + } + } + } } ] }, @@ -2802,6 +2883,123 @@ ] ] } + }, + { + "description": "Insert invoice with deep jsonb metadata", + "action": "merge", + "schema_id": "invoice", + "data": { + "id": "11111111-2222-3333-4444-555555555555", + "type": "invoice", + "number": "INV-1001", + "metadata": { + "internal_note": "Confidential", + "customer_snapshot": { + "id": "00000000-0000-0000-0000-000000000000", + "type": "person", + "first_name": "John" + }, + "related_rules": [ + { + "id": "11111111-1111-1111-1111-111111111111", + "type": "entity" + } + ] + } + }, + "expect": { + "success": true, + "sql": [ + [ + "SELECT to_jsonb(t1.*) || to_jsonb(t2.*)", + "FROM agreego.\"invoice\" t1", + "LEFT JOIN agreego.\"entity\" t2 ON t2.id = t1.id", + "WHERE t1.id = '11111111-2222-3333-4444-555555555555' OR (\"id\" = '11111111-2222-3333-4444-555555555555')" + ], + [ + "INSERT INTO agreego.\"entity\" (", + " \"created_at\",", + " \"created_by\",", + " \"id\",", + " \"modified_at\",", + " \"modified_by\",", + " \"type\"", + ")", + "VALUES (", + " '{{timestamp}}',", + " '00000000-0000-0000-0000-000000000000',", + " '11111111-2222-3333-4444-555555555555',", + " '{{timestamp}}',", + " '00000000-0000-0000-0000-000000000000',", + " 'invoice'", + ")" + ], + [ + "INSERT INTO agreego.\"invoice\" (", + " \"id\",", + " \"metadata\",", + " \"number\",", + " \"type\"", + ")", + "VALUES (", + " '11111111-2222-3333-4444-555555555555',", + " '{", + " \"customer_snapshot\":{", + " \"first_name\":\"John\",", + " \"id\":\"00000000-0000-0000-0000-000000000000\",", + " \"type\":\"person\"", + " },", + " \"internal_note\":\"Confidential\",", + " \"related_rules\":[", + " {", + " \"id\":\"11111111-1111-1111-1111-111111111111\",", + " \"type\":\"entity\"", + " }", + " ]", + " }',", + " 'INV-1001',", + " 'invoice'", + ")" + ], + [ + "INSERT INTO agreego.change (", + " \"old\",", + " \"new\",", + " entity_id,", + " id,", + " kind,", + " modified_at,", + " modified_by", + ")", + "VALUES (", + " NULL,", + " '{", + " \"metadata\":{", + " \"customer_snapshot\":{", + " \"first_name\":\"John\",", + " \"id\":\"00000000-0000-0000-0000-000000000000\",", + " \"type\":\"person\"", + " },", + " \"internal_note\":\"Confidential\",", + " \"related_rules\":[", + " {", + " \"id\":\"11111111-1111-1111-1111-111111111111\",", + " \"type\":\"entity\"", + " }", + " ]", + " },", + " \"number\":\"INV-1001\",", + " \"type\":\"invoice\"", + " }',", + " '11111111-2222-3333-4444-555555555555',", + " '{{uuid}}',", + " 'create',", + " '{{timestamp}}',", + " '00000000-0000-0000-0000-000000000000'", + ")" + ] + ] + } } ] } diff --git a/fixtures/queryer.json b/fixtures/queryer.json index 0019ceb..ce36294 100644 --- a/fixtures/queryer.json +++ b/fixtures/queryer.json @@ -1,1957 +1,2064 @@ [ - { - "description": "Queryer Execution", - "database": { - "puncs": [ - { - "name": "get_organization", - "schemas": { - "get_organization.response": { - "type": "organization" - } - } - }, - { - "name": "get_organizations", - "schemas": { - "get_organizations.response": { - "type": "array", - "items": { - "$family": "organization" - } - } - } - }, - { - "name": "get_light_organization", - "schemas": { - "get_light_organization.response": { - "$family": "light.organization" - } - } - }, - { - "name": "get_full_organization", - "schemas": { - "get_full_organization.response": { - "$family": "full.organization" - } - } - }, - { - "name": "get_orders", - "schemas": { - "get_orders.response": { - "type": "array", - "items": { - "type": "light.order" - } - } - } - }, - { - "name": "get_widgets", - "schemas": { - "get_widgets.response": { - "type": "array", - "items": { - "$family": "widget" - } - } - } - } - ], - "enums": [], - "relations": [ - { - "type": "relation", - "id": "00000000-0000-0000-0000-000000000001", - "constraint": "fk_relationship_source_entity", - "source_type": "relationship", - "source_columns": [ - "source_id", - "source_type" - ], - "destination_type": "entity", - "destination_columns": [ - "id", - "type" - ], - "prefix": "source" - }, - { - "type": "relation", - "id": "00000000-0000-0000-0000-000000000002", - "constraint": "fk_relationship_target_entity", - "source_type": "relationship", - "source_columns": [ - "target_id", - "target_type" - ], - "destination_type": "entity", - "destination_columns": [ - "id", - "type" - ], - "prefix": "target" - }, - { - "id": "22222222-2222-2222-2222-222222222222", - "type": "relation", - "constraint": "fk_order_customer_person", - "source_type": "order", - "source_columns": [ - "customer_id" - ], - "destination_type": "person", - "destination_columns": [ - "id" - ], - "prefix": "customer" - }, - { - "id": "22222222-2222-2222-2222-222222222227", - "type": "relation", - "constraint": "fk_order_counterparty_entity", - "source_type": "order", - "source_columns": [ - "counterparty_id", - "counterparty_type" - ], - "destination_type": "entity", - "destination_columns": [ - "id", - "type" - ], - "prefix": "counterparty" - }, - { - "id": "33333333-3333-3333-3333-333333333333", - "type": "relation", - "constraint": "fk_order_line_order", - "source_type": "order_line", - "source_columns": [ - "order_id" - ], - "destination_type": "order", - "destination_columns": [ - "id" - ] - } - ], - "types": [ - { - "name": "entity", - "hierarchy": [ - "entity" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ] - }, - "field_types": { - "id": "uuid", - "archived": "boolean", - "created_at": "timestamptz", - "type": "text" - }, - "schemas": { - "entity": { - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "type": "string" - }, - "archived": { - "type": "boolean" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "created": { - "type": "boolean" - } - } - } - }, - "fields": [ - "id", - "type", - "archived", - "created_at" - ], - "variations": [ - "address", - "bot", - "contact", - "email_address", - "entity", - "order", - "order_line", - "organization", - "person", - "phone_number", - "relationship" - ] - }, - { - "name": "organization", - "hierarchy": [ - "organization", - "entity" - ], - "fields": [ - "id", - "type", - "name", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "organization": [ - "name" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "name": "text", - "created_at": "timestamptz" - }, - "lookup_fields": [ - "id" - ], - "null_fields": [], - "default_fields": [ - "id", - "type", - "created_at", - "archived" - ], - "variations": [ - "bot", - "organization", - "person" - ], - "schemas": { - "organization": { - "type": "entity", - "properties": { - "name": { - "type": "string" - } - } - } - } - }, - { - "name": "bot", - "hierarchy": [ - "bot", - "organization", - "entity" - ], - "fields": [ - "token", - "id", - "type", - "name", - "archived", - "created_at", - "token", - "role" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "organization": [ - "name" - ], - "bot": [ - "token", - "role" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "name": "text", - "token": "text", - "role": "text", - "created_at": "timestamptz" - }, - "schemas": { - "bot": { - "type": "organization", - "properties": { - "token": { - "type": "string" - }, - "role": { - "type": "string" - } - } - }, - "light.bot": { - "type": "organization", - "properties": { - "token": { - "type": "string" - } - } - } - }, - "variations": [ - "bot" - ] - }, - { - "name": "person", - "hierarchy": [ - "person", - "organization", - "entity" - ], - "fields": [ - "first_name", - "last_name", - "id", - "type", - "name", - "age", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "organization": [ - "name" - ], - "person": [ - "first_name", - "last_name", - "age" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "first_name": "text", - "last_name": "text", - "name": "text", - "age": "numeric", - "created_at": "timestamptz" - }, - "schemas": { - "person": { - "type": "organization", - "properties": { - "first_name": { - "type": "string" - }, - "last_name": { - "type": "string" - }, - "age": { - "type": "number" - } - } - }, - "light.person": { - "type": "organization", - "properties": { - "first_name": { - "type": "string" - }, - "last_name": { - "type": "string" - } - } - }, - "full.person": { - "type": "person", - "properties": { - "phone_numbers": { - "type": "array", - "items": { - "type": "contact", - "properties": { - "target": { - "type": "phone_number" - } + { + "description": "Queryer Execution", + "database": { + "puncs": [ + { + "name": "get_organization", + "schemas": { + "get_organization.response": { + "type": "organization" + } } - } }, - "email_addresses": { - "type": "array", - "items": { - "type": "contact", - "properties": { - "target": { - "type": "email_address" - } + { + "name": "get_organizations", + "schemas": { + "get_organizations.response": { + "type": "array", + "items": { + "$family": "organization" + } + } } - } }, - "addresses": { - "type": "array", - "items": { - "type": "contact", - "properties": { - "target": { - "type": "address" - } + { + "name": "get_light_organization", + "schemas": { + "get_light_organization.response": { + "$family": "light.organization" + } } - } }, - "contacts": { - "type": "array", - "items": { - "type": "contact", - "properties": { - "target": { - "oneOf": [ - { - "type": "phone_number" - }, - { - "type": "email_address" - }, - { - "type": "address" - } + { + "name": "get_full_organization", + "schemas": { + "get_full_organization.response": { + "$family": "full.organization" + } + } + }, + { + "name": "get_orders", + "schemas": { + "get_orders.response": { + "type": "array", + "items": { + "type": "light.order" + } + } + } + }, + { + "name": "get_widgets", + "schemas": { + "get_widgets.response": { + "type": "array", + "items": { + "$family": "widget" + } + } + } + } + ], + "enums": [], + "relations": [ + { + "type": "relation", + "id": "00000000-0000-0000-0000-000000000001", + "constraint": "fk_relationship_source_entity", + "source_type": "relationship", + "source_columns": [ + "source_id", + "source_type" + ], + "destination_type": "entity", + "destination_columns": [ + "id", + "type" + ], + "prefix": "source" + }, + { + "type": "relation", + "id": "00000000-0000-0000-0000-000000000002", + "constraint": "fk_relationship_target_entity", + "source_type": "relationship", + "source_columns": [ + "target_id", + "target_type" + ], + "destination_type": "entity", + "destination_columns": [ + "id", + "type" + ], + "prefix": "target" + }, + { + "id": "22222222-2222-2222-2222-222222222222", + "type": "relation", + "constraint": "fk_order_customer_person", + "source_type": "order", + "source_columns": [ + "customer_id" + ], + "destination_type": "person", + "destination_columns": [ + "id" + ], + "prefix": "customer" + }, + { + "id": "22222222-2222-2222-2222-222222222227", + "type": "relation", + "constraint": "fk_order_counterparty_entity", + "source_type": "order", + "source_columns": [ + "counterparty_id", + "counterparty_type" + ], + "destination_type": "entity", + "destination_columns": [ + "id", + "type" + ], + "prefix": "counterparty" + }, + { + "id": "33333333-3333-3333-3333-333333333333", + "type": "relation", + "constraint": "fk_order_line_order", + "source_type": "order_line", + "source_columns": [ + "order_id" + ], + "destination_type": "order", + "destination_columns": [ + "id" + ] + } + ], + "types": [ + { + "name": "entity", + "hierarchy": [ + "entity" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" ] - } + }, + "field_types": { + "id": "uuid", + "archived": "boolean", + "created_at": "timestamptz", + "type": "text" + }, + "schemas": { + "entity": { + "type": "object", + "properties": { + "id": { + "type": "string", + "format": "uuid" + }, + "type": { + "type": "string" + }, + "archived": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "created": { + "type": "boolean" + } + } + } + }, + "fields": [ + "id", + "type", + "archived", + "created_at" + ], + "variations": [ + "address", + "bot", + "contact", + "email_address", + "entity", + "order", + "order_line", + "organization", + "person", + "phone_number", + "relationship" + ] + }, + { + "name": "organization", + "hierarchy": [ + "organization", + "entity" + ], + "fields": [ + "id", + "type", + "name", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "organization": [ + "name" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "name": "text", + "created_at": "timestamptz" + }, + "lookup_fields": [ + "id" + ], + "null_fields": [], + "default_fields": [ + "id", + "type", + "created_at", + "archived" + ], + "variations": [ + "bot", + "organization", + "person" + ], + "schemas": { + "organization": { + "type": "entity", + "properties": { + "name": { + "type": "string" + } + } + } } - } - } - } - } - }, - "variations": [ - "person" - ] - }, - { - "name": "relationship", - "relationship": true, - "hierarchy": [ - "relationship", - "entity" - ], - "fields": [ - "source_id", - "source_type", - "target_id", - "target_type", - "id", - "type", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "relationship": [ - "source_id", - "source_type", - "target_id", - "target_type" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "source_id": "uuid", - "source_type": "text", - "target_id": "uuid", - "target_type": "text", - "created_at": "timestamptz" - }, - "schemas": { - "relationship": { - "type": "entity", - "properties": {} - } - }, - "variations": [ - "contact", - "relationship" - ] - }, - { - "name": "contact", - "relationship": true, - "hierarchy": [ - "contact", - "relationship", - "entity" - ], - "fields": [ - "is_primary", - "source_id", - "source_type", - "target_id", - "target_type", - "id", - "type", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "relationship": [ - "source_id", - "source_type", - "target_id", - "target_type" - ], - "contact": [ - "is_primary" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "source_id": "uuid", - "source_type": "text", - "target_id": "uuid", - "target_type": "text", - "is_primary": "boolean", - "created_at": "timestamptz" - }, - "schemas": { - "contact": { - "type": "relationship", - "properties": { - "is_primary": { - "type": "boolean" - } - } - } - }, - "variations": [ - "contact" - ] - }, - { - "name": "phone_number", - "hierarchy": [ - "phone_number", - "entity" - ], - "fields": [ - "number", - "id", - "type", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "phone_number": [ - "number" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "number": "text", - "created_at": "timestamptz" - }, - "schemas": { - "phone_number": { - "type": "entity", - "properties": { - "number": { - "type": "string" - } - } - } - }, - "variations": [ - "phone_number" - ] - }, - { - "name": "email_address", - "hierarchy": [ - "email_address", - "entity" - ], - "fields": [ - "address", - "id", - "type", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "email_address": [ - "address" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "address": "text", - "created_at": "timestamptz" - }, - "schemas": { - "email_address": { - "type": "entity", - "properties": { - "address": { - "type": "string" - } - } - } - }, - "variations": [ - "email_address" - ] - }, - { - "name": "address", - "hierarchy": [ - "address", - "entity" - ], - "fields": [ - "city", - "id", - "type", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "address": [ - "city" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "city": "text", - "created_at": "timestamptz" - }, - "schemas": { - "address": { - "type": "entity", - "properties": { - "city": { - "type": "string" - } - } - } - }, - "variations": [ - "address" - ] - }, - { - "name": "order", - "schemas": { - "order": { - "type": "entity", - "properties": { - "total": { - "type": "number" }, - "customer_id": { - "type": "string" - } - } - }, - "light.order": { - "type": "order", - "properties": { - "customer": { - "type": "person" - } - } - }, - "full.order": { - "type": "order", - "properties": { - "customer": { - "type": "person" + { + "name": "bot", + "hierarchy": [ + "bot", + "organization", + "entity" + ], + "fields": [ + "token", + "id", + "type", + "name", + "archived", + "created_at", + "token", + "role" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "organization": [ + "name" + ], + "bot": [ + "token", + "role" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "name": "text", + "token": "text", + "role": "text", + "created_at": "timestamptz" + }, + "schemas": { + "bot": { + "type": "organization", + "properties": { + "token": { + "type": "string" + }, + "role": { + "type": "string" + } + } + }, + "light.bot": { + "type": "organization", + "properties": { + "token": { + "type": "string" + } + } + } + }, + "variations": [ + "bot" + ] }, - "lines": { - "type": "array", - "items": { - "type": "order_line" - } - } - } - } - }, - "hierarchy": [ - "order", - "entity" - ], - "fields": [ - "id", - "type", - "total", - "customer_id", - "created_at", - "created_by", - "modified_at", - "modified_by", - "archived", - "counterparty_id", - "counterparty_type" - ], - "grouped_fields": { - "order": [ - "id", - "type", - "total", - "customer_id", - "counterparty_id", - "counterparty_type" - ], - "entity": [ - "id", - "type", - "created_at", - "created_by", - "modified_at", - "modified_by", - "archived" - ] - }, - "lookup_fields": [ - "id" - ], - "historical": true, - "relationship": false, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "total": "numeric", - "customer_id": "uuid", - "created_at": "timestamptz", - "created_by": "uuid", - "modified_at": "timestamptz", - "modified_by": "uuid", - "counterparty_id": "uuid", - "counterparty_type": "text" - }, - "variations": [ - "order" - ] - }, - { - "name": "order_line", - "schemas": { - "order_line": { - "type": "entity", - "properties": { - "order_id": { - "type": "string" + { + "name": "person", + "hierarchy": [ + "person", + "organization", + "entity" + ], + "fields": [ + "first_name", + "last_name", + "id", + "type", + "name", + "age", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "organization": [ + "name" + ], + "person": [ + "first_name", + "last_name", + "age" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "first_name": "text", + "last_name": "text", + "name": "text", + "age": "numeric", + "created_at": "timestamptz" + }, + "schemas": { + "person": { + "type": "organization", + "properties": { + "first_name": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "age": { + "type": "number" + } + } + }, + "light.person": { + "type": "organization", + "properties": { + "first_name": { + "type": "string" + }, + "last_name": { + "type": "string" + } + } + }, + "full.person": { + "type": "person", + "properties": { + "phone_numbers": { + "type": "array", + "items": { + "type": "contact", + "properties": { + "target": { + "type": "phone_number" + } + } + } + }, + "email_addresses": { + "type": "array", + "items": { + "type": "contact", + "properties": { + "target": { + "type": "email_address" + } + } + } + }, + "addresses": { + "type": "array", + "items": { + "type": "contact", + "properties": { + "target": { + "type": "address" + } + } + } + }, + "contacts": { + "type": "array", + "items": { + "type": "contact", + "properties": { + "target": { + "oneOf": [ + { + "type": "phone_number" + }, + { + "type": "email_address" + }, + { + "type": "address" + } + ] + } + } + } + } + } + } + }, + "variations": [ + "person" + ] }, - "product": { - "type": "string" + { + "name": "relationship", + "relationship": true, + "hierarchy": [ + "relationship", + "entity" + ], + "fields": [ + "source_id", + "source_type", + "target_id", + "target_type", + "id", + "type", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "relationship": [ + "source_id", + "source_type", + "target_id", + "target_type" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "source_id": "uuid", + "source_type": "text", + "target_id": "uuid", + "target_type": "text", + "created_at": "timestamptz" + }, + "schemas": { + "relationship": { + "type": "entity", + "properties": {} + } + }, + "variations": [ + "contact", + "relationship" + ] }, - "price": { - "type": "number" + { + "name": "contact", + "relationship": true, + "hierarchy": [ + "contact", + "relationship", + "entity" + ], + "fields": [ + "is_primary", + "source_id", + "source_type", + "target_id", + "target_type", + "id", + "type", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "relationship": [ + "source_id", + "source_type", + "target_id", + "target_type" + ], + "contact": [ + "is_primary" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "source_id": "uuid", + "source_type": "text", + "target_id": "uuid", + "target_type": "text", + "is_primary": "boolean", + "created_at": "timestamptz" + }, + "schemas": { + "contact": { + "type": "relationship", + "properties": { + "is_primary": { + "type": "boolean" + } + } + } + }, + "variations": [ + "contact" + ] + }, + { + "name": "phone_number", + "hierarchy": [ + "phone_number", + "entity" + ], + "fields": [ + "number", + "id", + "type", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "phone_number": [ + "number" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "number": "text", + "created_at": "timestamptz" + }, + "schemas": { + "phone_number": { + "type": "entity", + "properties": { + "number": { + "type": "string" + } + } + } + }, + "variations": [ + "phone_number" + ] + }, + { + "name": "email_address", + "hierarchy": [ + "email_address", + "entity" + ], + "fields": [ + "address", + "id", + "type", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "email_address": [ + "address" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "address": "text", + "created_at": "timestamptz" + }, + "schemas": { + "email_address": { + "type": "entity", + "properties": { + "address": { + "type": "string" + } + } + } + }, + "variations": [ + "email_address" + ] + }, + { + "name": "address", + "hierarchy": [ + "address", + "entity" + ], + "fields": [ + "city", + "id", + "type", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "address": [ + "city" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "city": "text", + "created_at": "timestamptz" + }, + "schemas": { + "address": { + "type": "entity", + "properties": { + "city": { + "type": "string" + } + } + } + }, + "variations": [ + "address" + ] + }, + { + "name": "order", + "schemas": { + "order": { + "type": "entity", + "properties": { + "total": { + "type": "number" + }, + "customer_id": { + "type": "string" + } + } + }, + "light.order": { + "type": "order", + "properties": { + "customer": { + "type": "person" + } + } + }, + "full.order": { + "type": "order", + "properties": { + "customer": { + "type": "person" + }, + "lines": { + "type": "array", + "items": { + "type": "order_line" + } + } + } + } + }, + "hierarchy": [ + "order", + "entity" + ], + "fields": [ + "id", + "type", + "total", + "customer_id", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived", + "counterparty_id", + "counterparty_type" + ], + "grouped_fields": { + "order": [ + "id", + "type", + "total", + "customer_id", + "counterparty_id", + "counterparty_type" + ], + "entity": [ + "id", + "type", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ] + }, + "lookup_fields": [ + "id" + ], + "historical": true, + "relationship": false, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "total": "numeric", + "customer_id": "uuid", + "created_at": "timestamptz", + "created_by": "uuid", + "modified_at": "timestamptz", + "modified_by": "uuid", + "counterparty_id": "uuid", + "counterparty_type": "text" + }, + "variations": [ + "order" + ] + }, + { + "name": "order_line", + "schemas": { + "order_line": { + "type": "entity", + "properties": { + "order_id": { + "type": "string" + }, + "product": { + "type": "string" + }, + "price": { + "type": "number" + } + } + } + }, + "hierarchy": [ + "order_line", + "entity" + ], + "fields": [ + "id", + "type", + "order_id", + "product", + "price", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ], + "grouped_fields": { + "order_line": [ + "id", + "type", + "order_id", + "product", + "price" + ], + "entity": [ + "id", + "type", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ] + }, + "lookup_fields": [], + "historical": true, + "relationship": false, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "order_id": "uuid", + "product": "text", + "price": "numeric", + "created_at": "timestamptz", + "created_by": "uuid", + "modified_at": "timestamptz", + "modified_by": "uuid" + }, + "variations": [ + "order_line" + ] + }, + { + "name": "widget", + "hierarchy": [ + "widget", + "entity" + ], + "fields": [ + "id", + "type", + "kind", + "archived", + "created_at" + ], + "grouped_fields": { + "entity": [ + "id", + "type", + "archived", + "created_at" + ], + "widget": [ + "kind" + ] + }, + "field_types": { + "id": "uuid", + "type": "text", + "kind": "text", + "archived": "boolean", + "created_at": "timestamptz" + }, + "variations": [ + "widget" + ], + "schemas": { + "widget": { + "type": "entity", + "properties": { + "kind": { + "type": "string" + } + } + }, + "stock.widget": { + "type": "widget", + "properties": {} + }, + "tasks.widget": { + "type": "widget", + "properties": {} + } + } + }, + { + "name": "invoice", + "hierarchy": [ + "invoice", + "entity" + ], + "fields": [ + "id", + "type", + "number", + "metadata", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ], + "grouped_fields": { + "invoice": [ + "id", + "type", + "number", + "metadata" + ], + "entity": [ + "id", + "type", + "created_at", + "created_by", + "modified_at", + "modified_by", + "archived" + ] + }, + "lookup_fields": [ + "id" + ], + "historical": true, + "relationship": false, + "field_types": { + "id": "uuid", + "type": "text", + "archived": "boolean", + "number": "text", + "metadata": "jsonb", + "created_at": "timestamptz", + "created_by": "uuid", + "modified_at": "timestamptz", + "modified_by": "uuid" + }, + "variations": [ + "invoice" + ], + "schemas": { + "invoice": { + "type": "entity", + "properties": { + "id": { + "type": "string" + }, + "number": { + "type": "string" + }, + "metadata": { + "type": "object", + "properties": { + "internal_note": { + "type": "string" + }, + "customer_snapshot": { + "type": "entity" + }, + "related_rules": { + "type": "array", + "items": { + "type": "entity" + } + } + } + } + } + } + } } - } - } - }, - "hierarchy": [ - "order_line", - "entity" - ], - "fields": [ - "id", - "type", - "order_id", - "product", - "price", - "created_at", - "created_by", - "modified_at", - "modified_by", - "archived" - ], - "grouped_fields": { - "order_line": [ - "id", - "type", - "order_id", - "product", - "price" - ], - "entity": [ - "id", - "type", - "created_at", - "created_by", - "modified_at", - "modified_by", - "archived" ] - }, - "lookup_fields": [], - "historical": true, - "relationship": false, - "field_types": { - "id": "uuid", - "type": "text", - "archived": "boolean", - "order_id": "uuid", - "product": "text", - "price": "numeric", - "created_at": "timestamptz", - "created_by": "uuid", - "modified_at": "timestamptz", - "modified_by": "uuid" - }, - "variations": [ - "order_line" - ] }, - { - "name": "widget", - "hierarchy": [ - "widget", - "entity" - ], - "fields": [ - "id", - "type", - "kind", - "archived", - "created_at" - ], - "grouped_fields": { - "entity": [ - "id", - "type", - "archived", - "created_at" - ], - "widget": [ - "kind" - ] - }, - "field_types": { - "id": "uuid", - "type": "text", - "kind": "text", - "archived": "boolean", - "created_at": "timestamptz" - }, - "variations": [ - "widget" - ], - "schemas": { - "widget": { - "type": "entity", - "properties": { - "kind": { - "type": "string" + "tests": [ + { + "description": "Simple entity select", + "action": "query", + "schema_id": "entity", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'archived', entity_1.archived,", + " 'created_at', entity_1.created_at,", + " 'id', entity_1.id,", + " 'type', entity_1.type)", + "FROM agreego.entity entity_1", + "WHERE NOT entity_1.archived)))" + ] + ] } - } }, - "stock.widget": { - "type": "widget", - "properties": {} + { + "description": "Simple entity select with multiple filters", + "action": "query", + "schema_id": "entity", + "filters": { + "id": { + "$eq": "123e4567-e89b-12d3-a456-426614174000", + "$ne": "123e4567-e89b-12d3-a456-426614174001", + "$in": [ + "123e4567-e89b-12d3-a456-426614174000" + ], + "$nin": [ + "123e4567-e89b-12d3-a456-426614174001" + ] + }, + "created_at": { + "$eq": "2023-01-01T00:00:00Z", + "$ne": "2023-01-02T00:00:00Z", + "$gt": "2022-01-01T00:00:00Z", + "$gte": "2022-01-02T00:00:00Z", + "$lt": "2024-01-01T00:00:00Z", + "$lte": "2024-01-02T00:00:00Z" + }, + "archived": { + "$eq": false, + "$ne": true + } + }, + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'archived', entity_1.archived,", + " 'created_at', entity_1.created_at,", + " 'id', entity_1.id,", + " 'type', entity_1.type", + ")", + "FROM agreego.entity entity_1", + "WHERE", + " NOT entity_1.archived", + " AND entity_1.archived = ($1#>>'{}')::boolean", + " AND entity_1.archived != ($2#>>'{}')::boolean", + " AND entity_1.created_at = ($3#>>'{}')::timestamptz", + " AND entity_1.created_at > ($4#>>'{}')::timestamptz", + " AND entity_1.created_at >= ($5#>>'{}')::timestamptz", + " AND entity_1.created_at < ($6#>>'{}')::timestamptz", + " AND entity_1.created_at <= ($7#>>'{}')::timestamptz", + " AND entity_1.created_at != ($8#>>'{}')::timestamptz", + " AND entity_1.id = ($9#>>'{}')::uuid", + " AND entity_1.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($10#>>'{}')::jsonb))", + " AND entity_1.id != ($11#>>'{}')::uuid", + " AND entity_1.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($12#>>'{}')::jsonb))", + ")))" + ] + ] + } }, - "tasks.widget": { - "type": "widget", - "properties": {} + { + "description": "Person select on base schema", + "action": "query", + "schema_id": "person", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'age', person_1.age,", + " 'archived', entity_3.archived,", + " 'created_at', entity_3.created_at,", + " 'first_name', person_1.first_name,", + " 'id', entity_3.id,", + " 'last_name', person_1.last_name,", + " 'name', organization_2.name,", + " 'type', entity_3.type)", + "FROM agreego.person person_1", + "JOIN agreego.organization organization_2 ON organization_2.id = person_1.id", + "JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id", + "WHERE NOT entity_3.archived)))" + ] + ] + } + }, + { + "description": "Person select on full schema", + "action": "query", + "schema_id": "full.person", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'addresses',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_6.archived,", + " 'created_at', entity_6.created_at,", + " 'id', entity_6.id,", + " 'is_primary', contact_4.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'archived', entity_8.archived,", + " 'city', address_7.city,", + " 'created_at', entity_8.created_at,", + " 'id', entity_8.id,", + " 'type', entity_8.type", + " )", + " FROM agreego.address address_7", + " JOIN agreego.entity entity_8 ON entity_8.id = address_7.id", + " WHERE", + " NOT entity_8.archived", + " AND relationship_5.target_id = entity_8.id),", + " 'type', entity_6.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_4", + " JOIN agreego.relationship relationship_5 ON relationship_5.id = contact_4.id", + " JOIN agreego.entity entity_6 ON entity_6.id = relationship_5.id", + " WHERE", + " NOT entity_6.archived", + " AND relationship_5.target_type = 'address'", + " AND relationship_5.source_id = entity_3.id),", + " 'age', person_1.age,", + " 'archived', entity_3.archived,", + " 'contacts',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_11.archived,", + " 'created_at', entity_11.created_at,", + " 'id', entity_11.id,", + " 'is_primary', contact_9.is_primary,", + " 'target', CASE", + " WHEN entity_11.target_type = 'address' THEN", + " ((SELECT jsonb_build_object(", + " 'archived', entity_13.archived,", + " 'city', address_12.city,", + " 'created_at', entity_13.created_at,", + " 'id', entity_13.id,", + " 'type', entity_13.type", + " )", + " FROM agreego.address address_12", + " JOIN agreego.entity entity_13 ON entity_13.id = address_12.id", + " WHERE", + " NOT entity_13.archived", + " AND relationship_10.target_id = entity_13.id))", + " WHEN entity_11.target_type = 'email_address' THEN", + " ((SELECT jsonb_build_object(", + " 'address', email_address_14.address,", + " 'archived', entity_15.archived,", + " 'created_at', entity_15.created_at,", + " 'id', entity_15.id,", + " 'type', entity_15.type", + " )", + " FROM agreego.email_address email_address_14", + " JOIN agreego.entity entity_15 ON entity_15.id = email_address_14.id", + " WHERE", + " NOT entity_15.archived", + " AND relationship_10.target_id = entity_15.id))", + " WHEN entity_11.target_type = 'phone_number' THEN", + " ((SELECT jsonb_build_object(", + " 'archived', entity_17.archived,", + " 'created_at', entity_17.created_at,", + " 'id', entity_17.id,", + " 'number', phone_number_16.number,", + " 'type', entity_17.type", + " )", + " FROM agreego.phone_number phone_number_16", + " JOIN agreego.entity entity_17 ON entity_17.id = phone_number_16.id", + " WHERE", + " NOT entity_17.archived", + " AND relationship_10.target_id = entity_17.id))", + " ELSE NULL END,", + " 'type', entity_11.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_9", + " JOIN agreego.relationship relationship_10 ON relationship_10.id = contact_9.id", + " JOIN agreego.entity entity_11 ON entity_11.id = relationship_10.id", + " WHERE", + " NOT entity_11.archived", + " AND relationship_10.source_id = entity_3.id),", + " 'created_at', entity_3.created_at,", + " 'email_addresses',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_20.archived,", + " 'created_at', entity_20.created_at,", + " 'id', entity_20.id,", + " 'is_primary', contact_18.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'address', email_address_21.address,", + " 'archived', entity_22.archived,", + " 'created_at', entity_22.created_at,", + " 'id', entity_22.id,", + " 'type', entity_22.type", + " )", + " FROM agreego.email_address email_address_21", + " JOIN agreego.entity entity_22 ON entity_22.id = email_address_21.id", + " WHERE", + " NOT entity_22.archived", + " AND relationship_19.target_id = entity_22.id),", + " 'type', entity_20.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_18", + " JOIN agreego.relationship relationship_19 ON relationship_19.id = contact_18.id", + " JOIN agreego.entity entity_20 ON entity_20.id = relationship_19.id", + " WHERE", + " NOT entity_20.archived", + " AND relationship_19.target_type = 'email_address'", + " AND relationship_19.source_id = entity_3.id),", + " 'first_name', person_1.first_name,", + " 'id', entity_3.id,", + " 'last_name', person_1.last_name,", + " 'name', organization_2.name,", + " 'phone_numbers',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_25.archived,", + " 'created_at', entity_25.created_at,", + " 'id', entity_25.id,", + " 'is_primary', contact_23.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'archived', entity_27.archived,", + " 'created_at', entity_27.created_at,", + " 'id', entity_27.id,", + " 'number', phone_number_26.number,", + " 'type', entity_27.type", + " )", + " FROM agreego.phone_number phone_number_26", + " JOIN agreego.entity entity_27 ON entity_27.id = phone_number_26.id", + " WHERE", + " NOT entity_27.archived", + " AND relationship_24.target_id = entity_27.id),", + " 'type', entity_25.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_23", + " JOIN agreego.relationship relationship_24 ON relationship_24.id = contact_23.id", + " JOIN agreego.entity entity_25 ON entity_25.id = relationship_24.id", + " WHERE", + " NOT entity_25.archived", + " AND relationship_24.target_type = 'phone_number'", + " AND relationship_24.source_id = entity_3.id),", + " 'type', entity_3.type", + ")", + "FROM agreego.person person_1", + "JOIN agreego.organization organization_2 ON organization_2.id = person_1.id", + "JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id", + "WHERE NOT entity_3.archived)))" + ] + ] + } + }, + { + "description": "Person select on full schema with filters", + "action": "query", + "schema_id": "full.person", + "filters": { + "age": { + "$eq": 30, + "$gt": 20, + "$gte": 20, + "$in": [ + 30, + 40 + ], + "$lt": 50, + "$lte": 50, + "$ne": 25, + "$nin": [ + 1, + 2 + ] + }, + "archived": { + "$eq": true, + "$ne": false + }, + "contacts": { + "is_primary": { + "$eq": true + } + }, + "created_at": { + "$eq": "2020-01-01T00:00:00Z", + "$gt": "2019-01-01T00:00:00Z", + "$gte": "2019-01-01T00:00:00Z", + "$lt": "2021-01-01T00:00:00Z", + "$lte": "2021-01-01T00:00:00Z", + "$ne": "2022-01-01T00:00:00Z" + }, + "first_name": { + "$eq": "Jane%", + "$gt": "A", + "$gte": "A", + "$in": [ + "Jane", + "John" + ], + "$lt": "Z", + "$lte": "Z", + "$ne": "Doe", + "$nin": [ + "Bob" + ] + }, + "id": { + "$eq": "00000000-0000-0000-0000-000000000001", + "$in": [ + "00000000-0000-0000-0000-000000000001" + ], + "$ne": "00000000-0000-0000-0000-000000000002", + "$nin": [ + "00000000-0000-0000-0000-000000000002" + ] + }, + "last_name": { + "$eq": "%Doe%", + "$ne": "%Smith%" + }, + "phone_numbers": { + "target": { + "number": { + "$eq": "555-1234" + } + } + } + }, + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'addresses',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_6.archived,", + " 'created_at', entity_6.created_at,", + " 'id', entity_6.id,", + " 'is_primary', contact_4.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'archived', entity_8.archived,", + " 'city', address_7.city,", + " 'created_at', entity_8.created_at,", + " 'id', entity_8.id,", + " 'type', entity_8.type", + " )", + " FROM agreego.address address_7", + " JOIN agreego.entity entity_8 ON entity_8.id = address_7.id", + " WHERE", + " NOT entity_8.archived", + " AND relationship_5.target_id = entity_8.id),", + " 'type', entity_6.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_4", + " JOIN agreego.relationship relationship_5 ON relationship_5.id = contact_4.id", + " JOIN agreego.entity entity_6 ON entity_6.id = relationship_5.id", + " WHERE", + " NOT entity_6.archived", + " AND relationship_5.target_type = 'address'", + " AND relationship_5.source_id = entity_3.id),", + " 'age', person_1.age,", + " 'archived', entity_3.archived,", + " 'contacts',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_11.archived,", + " 'created_at', entity_11.created_at,", + " 'id', entity_11.id,", + " 'is_primary', contact_9.is_primary,", + " 'target', CASE", + " WHEN entity_11.target_type = 'address' THEN", + " ((SELECT jsonb_build_object(", + " 'archived', entity_13.archived,", + " 'city', address_12.city,", + " 'created_at', entity_13.created_at,", + " 'id', entity_13.id,", + " 'type', entity_13.type", + " )", + " FROM agreego.address address_12", + " JOIN agreego.entity entity_13 ON entity_13.id = address_12.id", + " WHERE", + " NOT entity_13.archived", + " AND relationship_10.target_id = entity_13.id))", + " WHEN entity_11.target_type = 'email_address' THEN", + " ((SELECT jsonb_build_object(", + " 'address', email_address_14.address,", + " 'archived', entity_15.archived,", + " 'created_at', entity_15.created_at,", + " 'id', entity_15.id,", + " 'type', entity_15.type", + " )", + " FROM agreego.email_address email_address_14", + " JOIN agreego.entity entity_15 ON entity_15.id = email_address_14.id", + " WHERE", + " NOT entity_15.archived", + " AND relationship_10.target_id = entity_15.id))", + " WHEN entity_11.target_type = 'phone_number' THEN", + " ((SELECT jsonb_build_object(", + " 'archived', entity_17.archived,", + " 'created_at', entity_17.created_at,", + " 'id', entity_17.id,", + " 'number', phone_number_16.number,", + " 'type', entity_17.type", + " )", + " FROM agreego.phone_number phone_number_16", + " JOIN agreego.entity entity_17 ON entity_17.id = phone_number_16.id", + " WHERE", + " NOT entity_17.archived", + " AND relationship_10.target_id = entity_17.id))", + " ELSE NULL END,", + " 'type', entity_11.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_9", + " JOIN agreego.relationship relationship_10 ON relationship_10.id = contact_9.id", + " JOIN agreego.entity entity_11 ON entity_11.id = relationship_10.id", + " WHERE", + " NOT entity_11.archived", + " AND contact_9.is_primary = ($11#>>'{}')::boolean", + " AND relationship_10.source_id = entity_3.id),", + " 'created_at', entity_3.created_at,", + " 'email_addresses',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_20.archived,", + " 'created_at', entity_20.created_at,", + " 'id', entity_20.id,", + " 'is_primary', contact_18.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'address', email_address_21.address,", + " 'archived', entity_22.archived,", + " 'created_at', entity_22.created_at,", + " 'id', entity_22.id,", + " 'type', entity_22.type", + " )", + " FROM agreego.email_address email_address_21", + " JOIN agreego.entity entity_22 ON entity_22.id = email_address_21.id", + " WHERE", + " NOT entity_22.archived", + " AND relationship_19.target_id = entity_22.id),", + " 'type', entity_20.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_18", + " JOIN agreego.relationship relationship_19 ON relationship_19.id = contact_18.id", + " JOIN agreego.entity entity_20 ON entity_20.id = relationship_19.id", + " WHERE", + " NOT entity_20.archived", + " AND relationship_19.target_type = 'email_address'", + " AND relationship_19.source_id = entity_3.id),", + " 'first_name', person_1.first_name,", + " 'id', entity_3.id,", + " 'last_name', person_1.last_name,", + " 'name', organization_2.name,", + " 'phone_numbers',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_25.archived,", + " 'created_at', entity_25.created_at,", + " 'id', entity_25.id,", + " 'is_primary', contact_23.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'archived', entity_27.archived,", + " 'created_at', entity_27.created_at,", + " 'id', entity_27.id,", + " 'number', phone_number_26.number,", + " 'type', entity_27.type", + " )", + " FROM agreego.phone_number phone_number_26", + " JOIN agreego.entity entity_27 ON entity_27.id = phone_number_26.id", + " WHERE", + " NOT entity_27.archived", + " AND phone_number_26.number ILIKE $32#>>'{}'", + " AND relationship_24.target_id = entity_27.id),", + " 'type', entity_25.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_23", + " JOIN agreego.relationship relationship_24 ON relationship_24.id = contact_23.id", + " JOIN agreego.entity entity_25 ON entity_25.id = relationship_24.id", + " WHERE", + " NOT entity_25.archived", + " AND relationship_24.target_type = 'phone_number'", + " AND relationship_24.source_id = entity_3.id),", + " 'type', entity_3.type", + ")", + "FROM agreego.person person_1", + "JOIN agreego.organization organization_2 ON organization_2.id = person_1.id", + "JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id", + "WHERE", + " NOT entity_3.archived", + " AND person_1.age = ($1#>>'{}')::numeric", + " AND person_1.age > ($2#>>'{}')::numeric", + " AND person_1.age >= ($3#>>'{}')::numeric", + " AND person_1.age IN (SELECT value::numeric FROM jsonb_array_elements_text(($4#>>'{}')::jsonb))", + " AND person_1.age < ($5#>>'{}')::numeric", + " AND person_1.age <= ($6#>>'{}')::numeric", + " AND person_1.age != ($7#>>'{}')::numeric", + " AND person_1.age NOT IN (SELECT value::numeric FROM jsonb_array_elements_text(($8#>>'{}')::jsonb))", + " AND entity_3.archived = ($9#>>'{}')::boolean", + " AND entity_3.archived != ($10#>>'{}')::boolean", + " AND entity_3.created_at = ($12#>>'{}')::timestamptz", + " AND entity_3.created_at > ($13#>>'{}')::timestamptz", + " AND entity_3.created_at >= ($14#>>'{}')::timestamptz", + " AND entity_3.created_at < ($15#>>'{}')::timestamptz", + " AND entity_3.created_at <= ($16#>>'{}')::timestamptz", + " AND entity_3.created_at != ($17#>>'{}')::timestamptz", + " AND person_1.first_name ILIKE $18#>>'{}'", + " AND person_1.first_name > ($19#>>'{}')", + " AND person_1.first_name >= ($20#>>'{}')", + " AND person_1.first_name IN (SELECT value FROM jsonb_array_elements_text(($21#>>'{}')::jsonb))", + " AND person_1.first_name < ($22#>>'{}')", + " AND person_1.first_name <= ($23#>>'{}')", + " AND person_1.first_name NOT ILIKE $24#>>'{}'", + " AND person_1.first_name NOT IN (SELECT value FROM jsonb_array_elements_text(($25#>>'{}')::jsonb))", + " AND entity_3.id = ($26#>>'{}')::uuid", + " AND entity_3.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($27#>>'{}')::jsonb))", + " AND entity_3.id != ($28#>>'{}')::uuid", + " AND entity_3.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($29#>>'{}')::jsonb))", + " AND person_1.last_name ILIKE $30#>>'{}'", + " AND person_1.last_name NOT ILIKE $31#>>'{}')))" + ] + ] + } + }, + { + "description": "Person ad-hoc email addresses select", + "action": "query", + "schema_id": "full.person/email_addresses", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_3.archived,", + " 'created_at', entity_3.created_at,", + " 'id', entity_3.id,", + " 'is_primary', contact_1.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'address', email_address_4.address,", + " 'archived', entity_5.archived,", + " 'created_at', entity_5.created_at,", + " 'id', entity_5.id,", + " 'type', entity_5.type", + " )", + " FROM agreego.email_address email_address_4", + " JOIN agreego.entity entity_5 ON entity_5.id = email_address_4.id", + " WHERE", + " NOT entity_5.archived", + " AND relationship_2.target_id = entity_5.id),", + " 'type', entity_3.type", + ")), '[]'::jsonb)", + "FROM agreego.contact contact_1", + "JOIN agreego.relationship relationship_2 ON relationship_2.id = contact_1.id", + "JOIN agreego.entity entity_3 ON entity_3.id = relationship_2.id", + "WHERE", + " NOT entity_3.archived", + " AND relationship_2.target_type = 'email_address')))" + ] + ] + } + }, + { + "description": "Order select with customer and lines", + "action": "query", + "schema_id": "full.order", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'archived', entity_2.archived,", + " 'created_at', entity_2.created_at,", + " 'customer',", + " (SELECT jsonb_build_object(", + " 'age', person_3.age,", + " 'archived', entity_5.archived,", + " 'created_at', entity_5.created_at,", + " 'first_name', person_3.first_name,", + " 'id', entity_5.id,", + " 'last_name', person_3.last_name,", + " 'name', organization_4.name,", + " 'type', entity_5.type", + " )", + " FROM agreego.person person_3", + " JOIN agreego.organization organization_4 ON organization_4.id = person_3.id", + " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", + " WHERE", + " NOT entity_5.archived", + " AND order_1.customer_id = person_3.id),", + " 'customer_id', order_1.customer_id,", + " 'id', entity_2.id,", + " 'lines',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_7.archived,", + " 'created_at', entity_7.created_at,", + " 'id', entity_7.id,", + " 'order_id', order_line_6.order_id,", + " 'price', order_line_6.price,", + " 'product', order_line_6.product,", + " 'type', entity_7.type", + " )), '[]'::jsonb)", + " FROM agreego.order_line order_line_6", + " JOIN agreego.entity entity_7 ON entity_7.id = order_line_6.id", + " WHERE", + " NOT entity_7.archived", + " AND order_line_6.order_id = order_1.id),", + " 'total', order_1.total,", + " 'type', entity_2.type", + ")", + "FROM agreego.order order_1", + "JOIN agreego.entity entity_2 ON entity_2.id = order_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Organization select via a punc response with ref", + "action": "query", + "schema_id": "get_organization.response", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'archived', entity_2.archived,", + " 'created_at', entity_2.created_at,", + " 'id', entity_2.id,", + " 'name', organization_1.name,", + " 'type', entity_2.type", + ")", + "FROM agreego.organization organization_1", + "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Organizations select via a punc response with family", + "action": "query", + "schema_id": "get_organizations.response", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(", + " CASE", + " WHEN organization_1.type = 'bot' THEN (", + " (SELECT jsonb_build_object(", + " 'archived', entity_5.archived,", + " 'created_at', entity_5.created_at,", + " 'id', entity_5.id,", + " 'name', organization_4.name,", + " 'role', bot_3.role,", + " 'token', bot_3.token,", + " 'type', entity_5.type", + " )", + " FROM agreego.bot bot_3", + " JOIN agreego.organization organization_4 ON organization_4.id = bot_3.id", + " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", + " WHERE", + " NOT entity_5.archived", + " AND entity_5.id = entity_2.id)", + " )", + " WHEN organization_1.type = 'organization' THEN (", + " (SELECT jsonb_build_object(", + " 'archived', entity_7.archived,", + " 'created_at', entity_7.created_at,", + " 'id', entity_7.id,", + " 'name', organization_6.name,", + " 'type', entity_7.type", + " )", + " FROM agreego.organization organization_6", + " JOIN agreego.entity entity_7 ON entity_7.id = organization_6.id", + " WHERE", + " NOT entity_7.archived", + " AND entity_7.id = entity_2.id)", + " )", + " WHEN organization_1.type = 'person' THEN (", + " (SELECT jsonb_build_object(", + " 'age', person_8.age,", + " 'archived', entity_10.archived,", + " 'created_at', entity_10.created_at,", + " 'first_name', person_8.first_name,", + " 'id', entity_10.id,", + " 'last_name', person_8.last_name,", + " 'name', organization_9.name,", + " 'type', entity_10.type", + " )", + " FROM agreego.person person_8", + " JOIN agreego.organization organization_9 ON organization_9.id = person_8.id", + " JOIN agreego.entity entity_10 ON entity_10.id = organization_9.id", + " WHERE", + " NOT entity_10.archived", + " AND entity_10.id = entity_2.id)", + " )", + " ELSE NULL", + " END", + "), '[]'::jsonb)", + "FROM agreego.organization organization_1", + "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Light organizations select via a punc response with family", + "action": "query", + "schema_id": "get_light_organization.response", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT ", + " CASE", + " WHEN organization_1.type = 'bot' THEN (", + " (SELECT jsonb_build_object(", + " 'archived', entity_5.archived,", + " 'created_at', entity_5.created_at,", + " 'id', entity_5.id,", + " 'name', organization_4.name,", + " 'token', bot_3.token,", + " 'type', entity_5.type", + " )", + " FROM agreego.bot bot_3", + " JOIN agreego.organization organization_4 ON organization_4.id = bot_3.id", + " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", + " WHERE NOT entity_5.archived AND entity_5.id = entity_2.id)", + " )", + " WHEN organization_1.type = 'person' THEN (", + " (SELECT jsonb_build_object(", + " 'archived', entity_8.archived,", + " 'created_at', entity_8.created_at,", + " 'first_name', person_6.first_name,", + " 'id', entity_8.id,", + " 'last_name', person_6.last_name,", + " 'name', organization_7.name,", + " 'type', entity_8.type", + " )", + " FROM agreego.person person_6", + " JOIN agreego.organization organization_7 ON organization_7.id = person_6.id", + " JOIN agreego.entity entity_8 ON entity_8.id = organization_7.id", + " WHERE NOT entity_8.archived AND entity_8.id = entity_2.id)", + " )", + " ELSE NULL", + " END", + "FROM agreego.organization organization_1", + "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Full organizations select via a punc response with family", + "action": "query", + "schema_id": "get_full_organization.response", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT CASE", + " WHEN organization_1.type = 'person' THEN (", + " (SELECT jsonb_build_object(", + " 'addresses',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_8.archived,", + " 'created_at', entity_8.created_at,", + " 'id', entity_8.id,", + " 'is_primary', contact_6.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'archived', entity_10.archived,", + " 'city', address_9.city,", + " 'created_at', entity_10.created_at,", + " 'id', entity_10.id,", + " 'type', entity_10.type", + " )", + " FROM agreego.address address_9", + " JOIN agreego.entity entity_10 ON entity_10.id = address_9.id", + " WHERE", + " NOT entity_10.archived", + " AND relationship_7.target_id = entity_10.id),", + " 'type', entity_8.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_6", + " JOIN agreego.relationship relationship_7 ON relationship_7.id = contact_6.id", + " JOIN agreego.entity entity_8 ON entity_8.id = relationship_7.id", + " WHERE", + " NOT entity_8.archived", + " AND relationship_7.target_type = 'address'", + " AND relationship_7.source_id = entity_5.id),", + " 'age', person_3.age,", + " 'archived', entity_5.archived,", + " 'contacts',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_13.archived,", + " 'created_at', entity_13.created_at,", + " 'id', entity_13.id,", + " 'is_primary', contact_11.is_primary,", + " 'target',", + " CASE", + " WHEN entity_13.target_type = 'address' THEN (", + " (SELECT jsonb_build_object(", + " 'archived', entity_15.archived,", + " 'city', address_14.city,", + " 'created_at', entity_15.created_at,", + " 'id', entity_15.id,", + " 'type', entity_15.type", + " )", + " FROM agreego.address address_14", + " JOIN agreego.entity entity_15 ON entity_15.id = address_14.id", + " WHERE", + " NOT entity_15.archived", + " AND relationship_12.target_id = entity_15.id)", + " )", + " WHEN entity_13.target_type = 'email_address' THEN (", + " (SELECT jsonb_build_object(", + " 'address', email_address_16.address,", + " 'archived', entity_17.archived,", + " 'created_at', entity_17.created_at,", + " 'id', entity_17.id,", + " 'type', entity_17.type", + " )", + " FROM agreego.email_address email_address_16", + " JOIN agreego.entity entity_17 ON entity_17.id = email_address_16.id", + " WHERE", + " NOT entity_17.archived", + " AND relationship_12.target_id = entity_17.id)", + " )", + " WHEN entity_13.target_type = 'phone_number' THEN (", + " (SELECT jsonb_build_object(", + " 'archived', entity_19.archived,", + " 'created_at', entity_19.created_at,", + " 'id', entity_19.id,", + " 'number', phone_number_18.number,", + " 'type', entity_19.type", + " )", + " FROM agreego.phone_number phone_number_18", + " JOIN agreego.entity entity_19 ON entity_19.id = phone_number_18.id", + " WHERE", + " NOT entity_19.archived", + " AND relationship_12.target_id = entity_19.id)", + " )", + " ELSE NULL", + " END,", + " 'type', entity_13.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_11", + " JOIN agreego.relationship relationship_12 ON relationship_12.id = contact_11.id", + " JOIN agreego.entity entity_13 ON entity_13.id = relationship_12.id", + " WHERE", + " NOT entity_13.archived", + " AND relationship_12.source_id = entity_5.id),", + " 'created_at', entity_5.created_at,", + " 'email_addresses',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_22.archived,", + " 'created_at', entity_22.created_at,", + " 'id', entity_22.id,", + " 'is_primary', contact_20.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'address', email_address_23.address,", + " 'archived', entity_24.archived,", + " 'created_at', entity_24.created_at,", + " 'id', entity_24.id,", + " 'type', entity_24.type", + " )", + " FROM agreego.email_address email_address_23", + " JOIN agreego.entity entity_24 ON entity_24.id = email_address_23.id", + " WHERE", + " NOT entity_24.archived", + " AND relationship_21.target_id = entity_24.id),", + " 'type', entity_22.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_20", + " JOIN agreego.relationship relationship_21 ON relationship_21.id = contact_20.id", + " JOIN agreego.entity entity_22 ON entity_22.id = relationship_21.id", + " WHERE", + " NOT entity_22.archived", + " AND relationship_21.target_type = 'email_address'", + " AND relationship_21.source_id = entity_5.id),", + " 'first_name', person_3.first_name,", + " 'id', entity_5.id,", + " 'last_name', person_3.last_name,", + " 'name', organization_4.name,", + " 'phone_numbers',", + " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_27.archived,", + " 'created_at', entity_27.created_at,", + " 'id', entity_27.id,", + " 'is_primary', contact_25.is_primary,", + " 'target',", + " (SELECT jsonb_build_object(", + " 'archived', entity_29.archived,", + " 'created_at', entity_29.created_at,", + " 'id', entity_29.id,", + " 'number', phone_number_28.number,", + " 'type', entity_29.type", + " )", + " FROM agreego.phone_number phone_number_28", + " JOIN agreego.entity entity_29 ON entity_29.id = phone_number_28.id", + " WHERE", + " NOT entity_29.archived", + " AND relationship_26.target_id = entity_29.id),", + " 'type', entity_27.type", + " )), '[]'::jsonb)", + " FROM agreego.contact contact_25", + " JOIN agreego.relationship relationship_26 ON relationship_26.id = contact_25.id", + " JOIN agreego.entity entity_27 ON entity_27.id = relationship_26.id", + " WHERE", + " NOT entity_27.archived", + " AND relationship_26.target_type = 'phone_number'", + " AND relationship_26.source_id = entity_5.id),", + " 'type', entity_5.type", + " )", + " FROM agreego.person person_3", + " JOIN agreego.organization organization_4 ON organization_4.id = person_3.id", + " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", + " WHERE NOT entity_5.archived AND entity_5.id = entity_2.id))", + " ELSE NULL", + "END", + "FROM agreego.organization organization_1", + "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Orders select via a punc with items", + "action": "query", + "schema_id": "get_orders.response", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(jsonb_build_object(", + " 'archived', entity_2.archived,", + " 'created_at', entity_2.created_at,", + " 'customer',", + " (SELECT jsonb_build_object(", + " 'age', person_3.age,", + " 'archived', entity_5.archived,", + " 'created_at', entity_5.created_at,", + " 'first_name', person_3.first_name,", + " 'id', entity_5.id,", + " 'last_name', person_3.last_name,", + " 'name', organization_4.name,", + " 'type', entity_5.type", + " )", + " FROM agreego.person person_3", + " JOIN agreego.organization organization_4 ON organization_4.id = person_3.id", + " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", + " WHERE", + " NOT entity_5.archived", + " AND order_1.customer_id = person_3.id),", + " 'customer_id', order_1.customer_id,", + " 'id', entity_2.id,", + " 'total', order_1.total,", + " 'type', entity_2.type", + ")), '[]'::jsonb)", + "FROM agreego.order order_1", + "JOIN agreego.entity entity_2 ON entity_2.id = order_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Widgets select via a punc response with family (STI)", + "action": "query", + "schema_id": "get_widgets.response", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(", + " CASE", + " WHEN widget_1.kind = 'stock' THEN (", + " jsonb_build_object(", + " 'archived', entity_2.archived,", + " 'created_at', entity_2.created_at,", + " 'id', entity_2.id,", + " 'kind', widget_1.kind,", + " 'type', entity_2.type", + " )", + " )", + " WHEN widget_1.kind = 'tasks' THEN (", + " jsonb_build_object(", + " 'archived', entity_2.archived,", + " 'created_at', entity_2.created_at,", + " 'id', entity_2.id,", + " 'kind', widget_1.kind,", + " 'type', entity_2.type", + " )", + " )", + " ELSE NULL", + " END", + "), '[]'::jsonb)", + "FROM agreego.widget widget_1", + "JOIN agreego.entity entity_2 ON entity_2.id = widget_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } + }, + { + "description": "Query invoice with complex JSONB metadata field extraction", + "action": "query", + "schema_id": "invoice", + "expect": { + "success": true, + "sql": [ + [ + "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", + " 'archived', entity_2.archived,", + " 'created_at', entity_2.created_at,", + " 'id', entity_2.id,", + " 'metadata', invoice_1.metadata,", + " 'number', invoice_1.number,", + " 'type', entity_2.type", + ")", + "FROM agreego.invoice invoice_1", + "JOIN agreego.entity entity_2 ON entity_2.id = invoice_1.id", + "WHERE NOT entity_2.archived)))" + ] + ] + } } - } - } - ] - }, - "tests": [ - { - "description": "Simple entity select", - "action": "query", - "schema_id": "entity", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'archived', entity_1.archived,", - " 'created_at', entity_1.created_at,", - " 'id', entity_1.id,", - " 'type', entity_1.type)", - "FROM agreego.entity entity_1", - "WHERE NOT entity_1.archived)))" - ] - ] - } - }, - { - "description": "Simple entity select with multiple filters", - "action": "query", - "schema_id": "entity", - "filters": { - "id": { - "$eq": "123e4567-e89b-12d3-a456-426614174000", - "$ne": "123e4567-e89b-12d3-a456-426614174001", - "$in": [ - "123e4567-e89b-12d3-a456-426614174000" - ], - "$nin": [ - "123e4567-e89b-12d3-a456-426614174001" - ] - }, - "created_at": { - "$eq": "2023-01-01T00:00:00Z", - "$ne": "2023-01-02T00:00:00Z", - "$gt": "2022-01-01T00:00:00Z", - "$gte": "2022-01-02T00:00:00Z", - "$lt": "2024-01-01T00:00:00Z", - "$lte": "2024-01-02T00:00:00Z" - }, - "archived": { - "$eq": false, - "$ne": true - } - }, - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'archived', entity_1.archived,", - " 'created_at', entity_1.created_at,", - " 'id', entity_1.id,", - " 'type', entity_1.type", - ")", - "FROM agreego.entity entity_1", - "WHERE", - " NOT entity_1.archived", - " AND entity_1.archived = ($1#>>'{}')::boolean", - " AND entity_1.archived != ($2#>>'{}')::boolean", - " AND entity_1.created_at = ($3#>>'{}')::timestamptz", - " AND entity_1.created_at > ($4#>>'{}')::timestamptz", - " AND entity_1.created_at >= ($5#>>'{}')::timestamptz", - " AND entity_1.created_at < ($6#>>'{}')::timestamptz", - " AND entity_1.created_at <= ($7#>>'{}')::timestamptz", - " AND entity_1.created_at != ($8#>>'{}')::timestamptz", - " AND entity_1.id = ($9#>>'{}')::uuid", - " AND entity_1.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($10#>>'{}')::jsonb))", - " AND entity_1.id != ($11#>>'{}')::uuid", - " AND entity_1.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($12#>>'{}')::jsonb))", - ")))" - ] - ] - } - }, - { - "description": "Person select on base schema", - "action": "query", - "schema_id": "person", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'age', person_1.age,", - " 'archived', entity_3.archived,", - " 'created_at', entity_3.created_at,", - " 'first_name', person_1.first_name,", - " 'id', entity_3.id,", - " 'last_name', person_1.last_name,", - " 'name', organization_2.name,", - " 'type', entity_3.type)", - "FROM agreego.person person_1", - "JOIN agreego.organization organization_2 ON organization_2.id = person_1.id", - "JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id", - "WHERE NOT entity_3.archived)))" - ] - ] - } - }, - { - "description": "Person select on full schema", - "action": "query", - "schema_id": "full.person", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'addresses',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_6.archived,", - " 'created_at', entity_6.created_at,", - " 'id', entity_6.id,", - " 'is_primary', contact_4.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'archived', entity_8.archived,", - " 'city', address_7.city,", - " 'created_at', entity_8.created_at,", - " 'id', entity_8.id,", - " 'type', entity_8.type", - " )", - " FROM agreego.address address_7", - " JOIN agreego.entity entity_8 ON entity_8.id = address_7.id", - " WHERE", - " NOT entity_8.archived", - " AND relationship_5.target_id = entity_8.id),", - " 'type', entity_6.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_4", - " JOIN agreego.relationship relationship_5 ON relationship_5.id = contact_4.id", - " JOIN agreego.entity entity_6 ON entity_6.id = relationship_5.id", - " WHERE", - " NOT entity_6.archived", - " AND relationship_5.target_type = 'address'", - " AND relationship_5.source_id = entity_3.id),", - " 'age', person_1.age,", - " 'archived', entity_3.archived,", - " 'contacts',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_11.archived,", - " 'created_at', entity_11.created_at,", - " 'id', entity_11.id,", - " 'is_primary', contact_9.is_primary,", - " 'target', CASE", - " WHEN entity_11.target_type = 'address' THEN", - " ((SELECT jsonb_build_object(", - " 'archived', entity_13.archived,", - " 'city', address_12.city,", - " 'created_at', entity_13.created_at,", - " 'id', entity_13.id,", - " 'type', entity_13.type", - " )", - " FROM agreego.address address_12", - " JOIN agreego.entity entity_13 ON entity_13.id = address_12.id", - " WHERE", - " NOT entity_13.archived", - " AND relationship_10.target_id = entity_13.id))", - " WHEN entity_11.target_type = 'email_address' THEN", - " ((SELECT jsonb_build_object(", - " 'address', email_address_14.address,", - " 'archived', entity_15.archived,", - " 'created_at', entity_15.created_at,", - " 'id', entity_15.id,", - " 'type', entity_15.type", - " )", - " FROM agreego.email_address email_address_14", - " JOIN agreego.entity entity_15 ON entity_15.id = email_address_14.id", - " WHERE", - " NOT entity_15.archived", - " AND relationship_10.target_id = entity_15.id))", - " WHEN entity_11.target_type = 'phone_number' THEN", - " ((SELECT jsonb_build_object(", - " 'archived', entity_17.archived,", - " 'created_at', entity_17.created_at,", - " 'id', entity_17.id,", - " 'number', phone_number_16.number,", - " 'type', entity_17.type", - " )", - " FROM agreego.phone_number phone_number_16", - " JOIN agreego.entity entity_17 ON entity_17.id = phone_number_16.id", - " WHERE", - " NOT entity_17.archived", - " AND relationship_10.target_id = entity_17.id))", - " ELSE NULL END,", - " 'type', entity_11.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_9", - " JOIN agreego.relationship relationship_10 ON relationship_10.id = contact_9.id", - " JOIN agreego.entity entity_11 ON entity_11.id = relationship_10.id", - " WHERE", - " NOT entity_11.archived", - " AND relationship_10.source_id = entity_3.id),", - " 'created_at', entity_3.created_at,", - " 'email_addresses',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_20.archived,", - " 'created_at', entity_20.created_at,", - " 'id', entity_20.id,", - " 'is_primary', contact_18.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'address', email_address_21.address,", - " 'archived', entity_22.archived,", - " 'created_at', entity_22.created_at,", - " 'id', entity_22.id,", - " 'type', entity_22.type", - " )", - " FROM agreego.email_address email_address_21", - " JOIN agreego.entity entity_22 ON entity_22.id = email_address_21.id", - " WHERE", - " NOT entity_22.archived", - " AND relationship_19.target_id = entity_22.id),", - " 'type', entity_20.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_18", - " JOIN agreego.relationship relationship_19 ON relationship_19.id = contact_18.id", - " JOIN agreego.entity entity_20 ON entity_20.id = relationship_19.id", - " WHERE", - " NOT entity_20.archived", - " AND relationship_19.target_type = 'email_address'", - " AND relationship_19.source_id = entity_3.id),", - " 'first_name', person_1.first_name,", - " 'id', entity_3.id,", - " 'last_name', person_1.last_name,", - " 'name', organization_2.name,", - " 'phone_numbers',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_25.archived,", - " 'created_at', entity_25.created_at,", - " 'id', entity_25.id,", - " 'is_primary', contact_23.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'archived', entity_27.archived,", - " 'created_at', entity_27.created_at,", - " 'id', entity_27.id,", - " 'number', phone_number_26.number,", - " 'type', entity_27.type", - " )", - " FROM agreego.phone_number phone_number_26", - " JOIN agreego.entity entity_27 ON entity_27.id = phone_number_26.id", - " WHERE", - " NOT entity_27.archived", - " AND relationship_24.target_id = entity_27.id),", - " 'type', entity_25.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_23", - " JOIN agreego.relationship relationship_24 ON relationship_24.id = contact_23.id", - " JOIN agreego.entity entity_25 ON entity_25.id = relationship_24.id", - " WHERE", - " NOT entity_25.archived", - " AND relationship_24.target_type = 'phone_number'", - " AND relationship_24.source_id = entity_3.id),", - " 'type', entity_3.type", - ")", - "FROM agreego.person person_1", - "JOIN agreego.organization organization_2 ON organization_2.id = person_1.id", - "JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id", - "WHERE NOT entity_3.archived)))" - ] - ] - } - }, - { - "description": "Person select on full schema with filters", - "action": "query", - "schema_id": "full.person", - "filters": { - "age": { - "$eq": 30, - "$gt": 20, - "$gte": 20, - "$in": [ - 30, - 40 - ], - "$lt": 50, - "$lte": 50, - "$ne": 25, - "$nin": [ - 1, - 2 - ] - }, - "archived": { - "$eq": true, - "$ne": false - }, - "contacts": { - "is_primary": { - "$eq": true - } - }, - "created_at": { - "$eq": "2020-01-01T00:00:00Z", - "$gt": "2019-01-01T00:00:00Z", - "$gte": "2019-01-01T00:00:00Z", - "$lt": "2021-01-01T00:00:00Z", - "$lte": "2021-01-01T00:00:00Z", - "$ne": "2022-01-01T00:00:00Z" - }, - "first_name": { - "$eq": "Jane%", - "$gt": "A", - "$gte": "A", - "$in": [ - "Jane", - "John" - ], - "$lt": "Z", - "$lte": "Z", - "$ne": "Doe", - "$nin": [ - "Bob" - ] - }, - "id": { - "$eq": "00000000-0000-0000-0000-000000000001", - "$in": [ - "00000000-0000-0000-0000-000000000001" - ], - "$ne": "00000000-0000-0000-0000-000000000002", - "$nin": [ - "00000000-0000-0000-0000-000000000002" - ] - }, - "last_name": { - "$eq": "%Doe%", - "$ne": "%Smith%" - }, - "phone_numbers": { - "target": { - "number": { - "$eq": "555-1234" - } - } - } - }, - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'addresses',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_6.archived,", - " 'created_at', entity_6.created_at,", - " 'id', entity_6.id,", - " 'is_primary', contact_4.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'archived', entity_8.archived,", - " 'city', address_7.city,", - " 'created_at', entity_8.created_at,", - " 'id', entity_8.id,", - " 'type', entity_8.type", - " )", - " FROM agreego.address address_7", - " JOIN agreego.entity entity_8 ON entity_8.id = address_7.id", - " WHERE", - " NOT entity_8.archived", - " AND relationship_5.target_id = entity_8.id),", - " 'type', entity_6.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_4", - " JOIN agreego.relationship relationship_5 ON relationship_5.id = contact_4.id", - " JOIN agreego.entity entity_6 ON entity_6.id = relationship_5.id", - " WHERE", - " NOT entity_6.archived", - " AND relationship_5.target_type = 'address'", - " AND relationship_5.source_id = entity_3.id),", - " 'age', person_1.age,", - " 'archived', entity_3.archived,", - " 'contacts',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_11.archived,", - " 'created_at', entity_11.created_at,", - " 'id', entity_11.id,", - " 'is_primary', contact_9.is_primary,", - " 'target', CASE", - " WHEN entity_11.target_type = 'address' THEN", - " ((SELECT jsonb_build_object(", - " 'archived', entity_13.archived,", - " 'city', address_12.city,", - " 'created_at', entity_13.created_at,", - " 'id', entity_13.id,", - " 'type', entity_13.type", - " )", - " FROM agreego.address address_12", - " JOIN agreego.entity entity_13 ON entity_13.id = address_12.id", - " WHERE", - " NOT entity_13.archived", - " AND relationship_10.target_id = entity_13.id))", - " WHEN entity_11.target_type = 'email_address' THEN", - " ((SELECT jsonb_build_object(", - " 'address', email_address_14.address,", - " 'archived', entity_15.archived,", - " 'created_at', entity_15.created_at,", - " 'id', entity_15.id,", - " 'type', entity_15.type", - " )", - " FROM agreego.email_address email_address_14", - " JOIN agreego.entity entity_15 ON entity_15.id = email_address_14.id", - " WHERE", - " NOT entity_15.archived", - " AND relationship_10.target_id = entity_15.id))", - " WHEN entity_11.target_type = 'phone_number' THEN", - " ((SELECT jsonb_build_object(", - " 'archived', entity_17.archived,", - " 'created_at', entity_17.created_at,", - " 'id', entity_17.id,", - " 'number', phone_number_16.number,", - " 'type', entity_17.type", - " )", - " FROM agreego.phone_number phone_number_16", - " JOIN agreego.entity entity_17 ON entity_17.id = phone_number_16.id", - " WHERE", - " NOT entity_17.archived", - " AND relationship_10.target_id = entity_17.id))", - " ELSE NULL END,", - " 'type', entity_11.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_9", - " JOIN agreego.relationship relationship_10 ON relationship_10.id = contact_9.id", - " JOIN agreego.entity entity_11 ON entity_11.id = relationship_10.id", - " WHERE", - " NOT entity_11.archived", - " AND contact_9.is_primary = ($11#>>'{}')::boolean", - " AND relationship_10.source_id = entity_3.id),", - " 'created_at', entity_3.created_at,", - " 'email_addresses',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_20.archived,", - " 'created_at', entity_20.created_at,", - " 'id', entity_20.id,", - " 'is_primary', contact_18.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'address', email_address_21.address,", - " 'archived', entity_22.archived,", - " 'created_at', entity_22.created_at,", - " 'id', entity_22.id,", - " 'type', entity_22.type", - " )", - " FROM agreego.email_address email_address_21", - " JOIN agreego.entity entity_22 ON entity_22.id = email_address_21.id", - " WHERE", - " NOT entity_22.archived", - " AND relationship_19.target_id = entity_22.id),", - " 'type', entity_20.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_18", - " JOIN agreego.relationship relationship_19 ON relationship_19.id = contact_18.id", - " JOIN agreego.entity entity_20 ON entity_20.id = relationship_19.id", - " WHERE", - " NOT entity_20.archived", - " AND relationship_19.target_type = 'email_address'", - " AND relationship_19.source_id = entity_3.id),", - " 'first_name', person_1.first_name,", - " 'id', entity_3.id,", - " 'last_name', person_1.last_name,", - " 'name', organization_2.name,", - " 'phone_numbers',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_25.archived,", - " 'created_at', entity_25.created_at,", - " 'id', entity_25.id,", - " 'is_primary', contact_23.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'archived', entity_27.archived,", - " 'created_at', entity_27.created_at,", - " 'id', entity_27.id,", - " 'number', phone_number_26.number,", - " 'type', entity_27.type", - " )", - " FROM agreego.phone_number phone_number_26", - " JOIN agreego.entity entity_27 ON entity_27.id = phone_number_26.id", - " WHERE", - " NOT entity_27.archived", - " AND phone_number_26.number ILIKE $32#>>'{}'", - " AND relationship_24.target_id = entity_27.id),", - " 'type', entity_25.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_23", - " JOIN agreego.relationship relationship_24 ON relationship_24.id = contact_23.id", - " JOIN agreego.entity entity_25 ON entity_25.id = relationship_24.id", - " WHERE", - " NOT entity_25.archived", - " AND relationship_24.target_type = 'phone_number'", - " AND relationship_24.source_id = entity_3.id),", - " 'type', entity_3.type", - ")", - "FROM agreego.person person_1", - "JOIN agreego.organization organization_2 ON organization_2.id = person_1.id", - "JOIN agreego.entity entity_3 ON entity_3.id = organization_2.id", - "WHERE", - " NOT entity_3.archived", - " AND person_1.age = ($1#>>'{}')::numeric", - " AND person_1.age > ($2#>>'{}')::numeric", - " AND person_1.age >= ($3#>>'{}')::numeric", - " AND person_1.age IN (SELECT value::numeric FROM jsonb_array_elements_text(($4#>>'{}')::jsonb))", - " AND person_1.age < ($5#>>'{}')::numeric", - " AND person_1.age <= ($6#>>'{}')::numeric", - " AND person_1.age != ($7#>>'{}')::numeric", - " AND person_1.age NOT IN (SELECT value::numeric FROM jsonb_array_elements_text(($8#>>'{}')::jsonb))", - " AND entity_3.archived = ($9#>>'{}')::boolean", - " AND entity_3.archived != ($10#>>'{}')::boolean", - " AND entity_3.created_at = ($12#>>'{}')::timestamptz", - " AND entity_3.created_at > ($13#>>'{}')::timestamptz", - " AND entity_3.created_at >= ($14#>>'{}')::timestamptz", - " AND entity_3.created_at < ($15#>>'{}')::timestamptz", - " AND entity_3.created_at <= ($16#>>'{}')::timestamptz", - " AND entity_3.created_at != ($17#>>'{}')::timestamptz", - " AND person_1.first_name ILIKE $18#>>'{}'", - " AND person_1.first_name > ($19#>>'{}')", - " AND person_1.first_name >= ($20#>>'{}')", - " AND person_1.first_name IN (SELECT value FROM jsonb_array_elements_text(($21#>>'{}')::jsonb))", - " AND person_1.first_name < ($22#>>'{}')", - " AND person_1.first_name <= ($23#>>'{}')", - " AND person_1.first_name NOT ILIKE $24#>>'{}'", - " AND person_1.first_name NOT IN (SELECT value FROM jsonb_array_elements_text(($25#>>'{}')::jsonb))", - " AND entity_3.id = ($26#>>'{}')::uuid", - " AND entity_3.id IN (SELECT value::uuid FROM jsonb_array_elements_text(($27#>>'{}')::jsonb))", - " AND entity_3.id != ($28#>>'{}')::uuid", - " AND entity_3.id NOT IN (SELECT value::uuid FROM jsonb_array_elements_text(($29#>>'{}')::jsonb))", - " AND person_1.last_name ILIKE $30#>>'{}'", - " AND person_1.last_name NOT ILIKE $31#>>'{}')))" - ] - ] - } - }, - { - "description": "Person ad-hoc email addresses select", - "action": "query", - "schema_id": "full.person/email_addresses", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_3.archived,", - " 'created_at', entity_3.created_at,", - " 'id', entity_3.id,", - " 'is_primary', contact_1.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'address', email_address_4.address,", - " 'archived', entity_5.archived,", - " 'created_at', entity_5.created_at,", - " 'id', entity_5.id,", - " 'type', entity_5.type", - " )", - " FROM agreego.email_address email_address_4", - " JOIN agreego.entity entity_5 ON entity_5.id = email_address_4.id", - " WHERE", - " NOT entity_5.archived", - " AND relationship_2.target_id = entity_5.id),", - " 'type', entity_3.type", - ")), '[]'::jsonb)", - "FROM agreego.contact contact_1", - "JOIN agreego.relationship relationship_2 ON relationship_2.id = contact_1.id", - "JOIN agreego.entity entity_3 ON entity_3.id = relationship_2.id", - "WHERE", - " NOT entity_3.archived", - " AND relationship_2.target_type = 'email_address')))" - ] - ] - } - }, - { - "description": "Order select with customer and lines", - "action": "query", - "schema_id": "full.order", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'archived', entity_2.archived,", - " 'created_at', entity_2.created_at,", - " 'customer',", - " (SELECT jsonb_build_object(", - " 'age', person_3.age,", - " 'archived', entity_5.archived,", - " 'created_at', entity_5.created_at,", - " 'first_name', person_3.first_name,", - " 'id', entity_5.id,", - " 'last_name', person_3.last_name,", - " 'name', organization_4.name,", - " 'type', entity_5.type", - " )", - " FROM agreego.person person_3", - " JOIN agreego.organization organization_4 ON organization_4.id = person_3.id", - " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", - " WHERE", - " NOT entity_5.archived", - " AND order_1.customer_id = person_3.id),", - " 'customer_id', order_1.customer_id,", - " 'id', entity_2.id,", - " 'lines',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_7.archived,", - " 'created_at', entity_7.created_at,", - " 'id', entity_7.id,", - " 'order_id', order_line_6.order_id,", - " 'price', order_line_6.price,", - " 'product', order_line_6.product,", - " 'type', entity_7.type", - " )), '[]'::jsonb)", - " FROM agreego.order_line order_line_6", - " JOIN agreego.entity entity_7 ON entity_7.id = order_line_6.id", - " WHERE", - " NOT entity_7.archived", - " AND order_line_6.order_id = order_1.id),", - " 'total', order_1.total,", - " 'type', entity_2.type", - ")", - "FROM agreego.order order_1", - "JOIN agreego.entity entity_2 ON entity_2.id = order_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - }, - { - "description": "Organization select via a punc response with ref", - "action": "query", - "schema_id": "get_organization.response", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT jsonb_build_object(", - " 'archived', entity_2.archived,", - " 'created_at', entity_2.created_at,", - " 'id', entity_2.id,", - " 'name', organization_1.name,", - " 'type', entity_2.type", - ")", - "FROM agreego.organization organization_1", - "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - }, - { - "description": "Organizations select via a punc response with family", - "action": "query", - "schema_id": "get_organizations.response", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(", - " CASE", - " WHEN organization_1.type = 'bot' THEN (", - " (SELECT jsonb_build_object(", - " 'archived', entity_5.archived,", - " 'created_at', entity_5.created_at,", - " 'id', entity_5.id,", - " 'name', organization_4.name,", - " 'role', bot_3.role,", - " 'token', bot_3.token,", - " 'type', entity_5.type", - " )", - " FROM agreego.bot bot_3", - " JOIN agreego.organization organization_4 ON organization_4.id = bot_3.id", - " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", - " WHERE", - " NOT entity_5.archived", - " AND entity_5.id = entity_2.id)", - " )", - " WHEN organization_1.type = 'organization' THEN (", - " (SELECT jsonb_build_object(", - " 'archived', entity_7.archived,", - " 'created_at', entity_7.created_at,", - " 'id', entity_7.id,", - " 'name', organization_6.name,", - " 'type', entity_7.type", - " )", - " FROM agreego.organization organization_6", - " JOIN agreego.entity entity_7 ON entity_7.id = organization_6.id", - " WHERE", - " NOT entity_7.archived", - " AND entity_7.id = entity_2.id)", - " )", - " WHEN organization_1.type = 'person' THEN (", - " (SELECT jsonb_build_object(", - " 'age', person_8.age,", - " 'archived', entity_10.archived,", - " 'created_at', entity_10.created_at,", - " 'first_name', person_8.first_name,", - " 'id', entity_10.id,", - " 'last_name', person_8.last_name,", - " 'name', organization_9.name,", - " 'type', entity_10.type", - " )", - " FROM agreego.person person_8", - " JOIN agreego.organization organization_9 ON organization_9.id = person_8.id", - " JOIN agreego.entity entity_10 ON entity_10.id = organization_9.id", - " WHERE", - " NOT entity_10.archived", - " AND entity_10.id = entity_2.id)", - " )", - " ELSE NULL", - " END", - "), '[]'::jsonb)", - "FROM agreego.organization organization_1", - "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - }, - { - "description": "Light organizations select via a punc response with family", - "action": "query", - "schema_id": "get_light_organization.response", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT ", - " CASE", - " WHEN organization_1.type = 'bot' THEN (", - " (SELECT jsonb_build_object(", - " 'archived', entity_5.archived,", - " 'created_at', entity_5.created_at,", - " 'id', entity_5.id,", - " 'name', organization_4.name,", - " 'token', bot_3.token,", - " 'type', entity_5.type", - " )", - " FROM agreego.bot bot_3", - " JOIN agreego.organization organization_4 ON organization_4.id = bot_3.id", - " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", - " WHERE NOT entity_5.archived AND entity_5.id = entity_2.id)", - " )", - " WHEN organization_1.type = 'person' THEN (", - " (SELECT jsonb_build_object(", - " 'archived', entity_8.archived,", - " 'created_at', entity_8.created_at,", - " 'first_name', person_6.first_name,", - " 'id', entity_8.id,", - " 'last_name', person_6.last_name,", - " 'name', organization_7.name,", - " 'type', entity_8.type", - " )", - " FROM agreego.person person_6", - " JOIN agreego.organization organization_7 ON organization_7.id = person_6.id", - " JOIN agreego.entity entity_8 ON entity_8.id = organization_7.id", - " WHERE NOT entity_8.archived AND entity_8.id = entity_2.id)", - " )", - " ELSE NULL", - " END", - "FROM agreego.organization organization_1", - "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - }, - { - "description": "Full organizations select via a punc response with family", - "action": "query", - "schema_id": "get_full_organization.response", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT CASE", - " WHEN organization_1.type = 'person' THEN (", - " (SELECT jsonb_build_object(", - " 'addresses',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_8.archived,", - " 'created_at', entity_8.created_at,", - " 'id', entity_8.id,", - " 'is_primary', contact_6.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'archived', entity_10.archived,", - " 'city', address_9.city,", - " 'created_at', entity_10.created_at,", - " 'id', entity_10.id,", - " 'type', entity_10.type", - " )", - " FROM agreego.address address_9", - " JOIN agreego.entity entity_10 ON entity_10.id = address_9.id", - " WHERE", - " NOT entity_10.archived", - " AND relationship_7.target_id = entity_10.id),", - " 'type', entity_8.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_6", - " JOIN agreego.relationship relationship_7 ON relationship_7.id = contact_6.id", - " JOIN agreego.entity entity_8 ON entity_8.id = relationship_7.id", - " WHERE", - " NOT entity_8.archived", - " AND relationship_7.target_type = 'address'", - " AND relationship_7.source_id = entity_5.id),", - " 'age', person_3.age,", - " 'archived', entity_5.archived,", - " 'contacts',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_13.archived,", - " 'created_at', entity_13.created_at,", - " 'id', entity_13.id,", - " 'is_primary', contact_11.is_primary,", - " 'target',", - " CASE", - " WHEN entity_13.target_type = 'address' THEN (", - " (SELECT jsonb_build_object(", - " 'archived', entity_15.archived,", - " 'city', address_14.city,", - " 'created_at', entity_15.created_at,", - " 'id', entity_15.id,", - " 'type', entity_15.type", - " )", - " FROM agreego.address address_14", - " JOIN agreego.entity entity_15 ON entity_15.id = address_14.id", - " WHERE", - " NOT entity_15.archived", - " AND relationship_12.target_id = entity_15.id)", - " )", - " WHEN entity_13.target_type = 'email_address' THEN (", - " (SELECT jsonb_build_object(", - " 'address', email_address_16.address,", - " 'archived', entity_17.archived,", - " 'created_at', entity_17.created_at,", - " 'id', entity_17.id,", - " 'type', entity_17.type", - " )", - " FROM agreego.email_address email_address_16", - " JOIN agreego.entity entity_17 ON entity_17.id = email_address_16.id", - " WHERE", - " NOT entity_17.archived", - " AND relationship_12.target_id = entity_17.id)", - " )", - " WHEN entity_13.target_type = 'phone_number' THEN (", - " (SELECT jsonb_build_object(", - " 'archived', entity_19.archived,", - " 'created_at', entity_19.created_at,", - " 'id', entity_19.id,", - " 'number', phone_number_18.number,", - " 'type', entity_19.type", - " )", - " FROM agreego.phone_number phone_number_18", - " JOIN agreego.entity entity_19 ON entity_19.id = phone_number_18.id", - " WHERE", - " NOT entity_19.archived", - " AND relationship_12.target_id = entity_19.id)", - " )", - " ELSE NULL", - " END,", - " 'type', entity_13.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_11", - " JOIN agreego.relationship relationship_12 ON relationship_12.id = contact_11.id", - " JOIN agreego.entity entity_13 ON entity_13.id = relationship_12.id", - " WHERE", - " NOT entity_13.archived", - " AND relationship_12.source_id = entity_5.id),", - " 'created_at', entity_5.created_at,", - " 'email_addresses',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_22.archived,", - " 'created_at', entity_22.created_at,", - " 'id', entity_22.id,", - " 'is_primary', contact_20.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'address', email_address_23.address,", - " 'archived', entity_24.archived,", - " 'created_at', entity_24.created_at,", - " 'id', entity_24.id,", - " 'type', entity_24.type", - " )", - " FROM agreego.email_address email_address_23", - " JOIN agreego.entity entity_24 ON entity_24.id = email_address_23.id", - " WHERE", - " NOT entity_24.archived", - " AND relationship_21.target_id = entity_24.id),", - " 'type', entity_22.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_20", - " JOIN agreego.relationship relationship_21 ON relationship_21.id = contact_20.id", - " JOIN agreego.entity entity_22 ON entity_22.id = relationship_21.id", - " WHERE", - " NOT entity_22.archived", - " AND relationship_21.target_type = 'email_address'", - " AND relationship_21.source_id = entity_5.id),", - " 'first_name', person_3.first_name,", - " 'id', entity_5.id,", - " 'last_name', person_3.last_name,", - " 'name', organization_4.name,", - " 'phone_numbers',", - " (SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_27.archived,", - " 'created_at', entity_27.created_at,", - " 'id', entity_27.id,", - " 'is_primary', contact_25.is_primary,", - " 'target',", - " (SELECT jsonb_build_object(", - " 'archived', entity_29.archived,", - " 'created_at', entity_29.created_at,", - " 'id', entity_29.id,", - " 'number', phone_number_28.number,", - " 'type', entity_29.type", - " )", - " FROM agreego.phone_number phone_number_28", - " JOIN agreego.entity entity_29 ON entity_29.id = phone_number_28.id", - " WHERE", - " NOT entity_29.archived", - " AND relationship_26.target_id = entity_29.id),", - " 'type', entity_27.type", - " )), '[]'::jsonb)", - " FROM agreego.contact contact_25", - " JOIN agreego.relationship relationship_26 ON relationship_26.id = contact_25.id", - " JOIN agreego.entity entity_27 ON entity_27.id = relationship_26.id", - " WHERE", - " NOT entity_27.archived", - " AND relationship_26.target_type = 'phone_number'", - " AND relationship_26.source_id = entity_5.id),", - " 'type', entity_5.type", - " )", - " FROM agreego.person person_3", - " JOIN agreego.organization organization_4 ON organization_4.id = person_3.id", - " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", - " WHERE NOT entity_5.archived AND entity_5.id = entity_2.id))", - " ELSE NULL", - "END", - "FROM agreego.organization organization_1", - "JOIN agreego.entity entity_2 ON entity_2.id = organization_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - }, - { - "description": "Orders select via a punc with items", - "action": "query", - "schema_id": "get_orders.response", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(jsonb_build_object(", - " 'archived', entity_2.archived,", - " 'created_at', entity_2.created_at,", - " 'customer',", - " (SELECT jsonb_build_object(", - " 'age', person_3.age,", - " 'archived', entity_5.archived,", - " 'created_at', entity_5.created_at,", - " 'first_name', person_3.first_name,", - " 'id', entity_5.id,", - " 'last_name', person_3.last_name,", - " 'name', organization_4.name,", - " 'type', entity_5.type", - " )", - " FROM agreego.person person_3", - " JOIN agreego.organization organization_4 ON organization_4.id = person_3.id", - " JOIN agreego.entity entity_5 ON entity_5.id = organization_4.id", - " WHERE", - " NOT entity_5.archived", - " AND order_1.customer_id = person_3.id),", - " 'customer_id', order_1.customer_id,", - " 'id', entity_2.id,", - " 'total', order_1.total,", - " 'type', entity_2.type", - ")), '[]'::jsonb)", - "FROM agreego.order order_1", - "JOIN agreego.entity entity_2 ON entity_2.id = order_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - }, - { - "description": "Widgets select via a punc response with family (STI)", - "action": "query", - "schema_id": "get_widgets.response", - "expect": { - "success": true, - "sql": [ - [ - "(SELECT jsonb_strip_nulls((SELECT COALESCE(jsonb_agg(", - " CASE", - " WHEN widget_1.kind = 'stock' THEN (", - " jsonb_build_object(", - " 'archived', entity_2.archived,", - " 'created_at', entity_2.created_at,", - " 'id', entity_2.id,", - " 'kind', widget_1.kind,", - " 'type', entity_2.type", - " )", - " )", - " WHEN widget_1.kind = 'tasks' THEN (", - " jsonb_build_object(", - " 'archived', entity_2.archived,", - " 'created_at', entity_2.created_at,", - " 'id', entity_2.id,", - " 'kind', widget_1.kind,", - " 'type', entity_2.type", - " )", - " )", - " ELSE NULL", - " END", - "), '[]'::jsonb)", - "FROM agreego.widget widget_1", - "JOIN agreego.entity entity_2 ON entity_2.id = widget_1.id", - "WHERE NOT entity_2.archived)))" - ] - ] - } - } - ] - } + ] + } ] \ No newline at end of file diff --git a/src/tests/fixtures.rs b/src/tests/fixtures.rs index 5901b93..8d3371d 100644 --- a/src/tests/fixtures.rs +++ b/src/tests/fixtures.rs @@ -1451,6 +1451,12 @@ fn test_queryer_0_12() { crate::tests::runner::run_test_case(&path, 0, 12).unwrap(); } +#[test] +fn test_queryer_0_13() { + let path = format!("{}/fixtures/queryer.json", env!("CARGO_MANIFEST_DIR")); + crate::tests::runner::run_test_case(&path, 0, 13).unwrap(); +} + #[test] fn test_polymorphism_0_0() { let path = format!("{}/fixtures/polymorphism.json", env!("CARGO_MANIFEST_DIR")); @@ -8086,3 +8092,9 @@ fn test_merger_0_12() { let path = format!("{}/fixtures/merger.json", env!("CARGO_MANIFEST_DIR")); crate::tests::runner::run_test_case(&path, 0, 12).unwrap(); } + +#[test] +fn test_merger_0_13() { + let path = format!("{}/fixtures/merger.json", env!("CARGO_MANIFEST_DIR")); + crate::tests::runner::run_test_case(&path, 0, 13).unwrap(); +} diff --git a/wipe_test.py b/wipe_test.py new file mode 100644 index 0000000..580116d --- /dev/null +++ b/wipe_test.py @@ -0,0 +1,24 @@ +import json + +def load_json(path): + with open(path, 'r') as f: + return json.load(f) + +def save_json(path, data): + with open(path, 'w') as f: + json.dump(data, f, indent=4) + +def fix_merger(): + data = load_json('fixtures/merger.json') + last_test = data[0]['tests'][-1] + last_test["expect"]["sql"] = [] + save_json('fixtures/merger.json', data) + +def fix_queryer(): + data = load_json('fixtures/queryer.json') + last_test = data[0]['tests'][-1] + last_test["expect"]["sql"] = [] + save_json('fixtures/queryer.json', data) + +fix_merger() +fix_queryer()