{"id":25741006,"url":"https://github.com/mk3008/carbunqlex","last_synced_at":"2025-11-19T23:03:20.547Z","repository":{"id":266098587,"uuid":"897294580","full_name":"mk3008/CarbunqleX","owner":"mk3008","description":"CarbunqleX is a lightweight library that enhances the reusability and maintainability of RawSQL through advanced query parsing.","archived":false,"fork":false,"pushed_at":"2025-02-23T04:46:53.000Z","size":435,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-23T05:19:54.005Z","etag":null,"topics":["ast","csharp","csharp-lib","csharp-library","dynamic-query","postgres","postgres-sql-parser","postgresql","raw-sql","sql","sql-parser"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mk3008.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-02T11:36:45.000Z","updated_at":"2025-02-23T04:20:21.000Z","dependencies_parsed_at":"2024-12-02T15:37:57.754Z","dependency_job_id":"3118674c-96c3-40e7-8563-a987944e5cfe","html_url":"https://github.com/mk3008/CarbunqleX","commit_stats":null,"previous_names":["mk3008/carbunqlex"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk3008%2FCarbunqleX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk3008%2FCarbunqleX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk3008%2FCarbunqleX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mk3008%2FCarbunqleX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mk3008","download_url":"https://codeload.github.com/mk3008/CarbunqleX/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240822748,"owners_count":19863318,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ast","csharp","csharp-lib","csharp-library","dynamic-query","postgres","postgres-sql-parser","postgresql","raw-sql","sql","sql-parser"],"created_at":"2025-02-26T09:19:14.595Z","updated_at":"2025-11-19T23:03:20.541Z","avatar_url":"https://github.com/mk3008.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# CarbunqleX - SQL Parser and Modeler\n\n![GitHub](https://img.shields.io/github/license/mk3008/Carbunqlex)\n![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/mk3008/Carbunqlex)\n![Github Last commit](https://img.shields.io/github/last-commit/mk3008/Carbunqlex)  \n[![Carbunqlex](https://img.shields.io/nuget/v/Carbunqlex.svg)](https://www.nuget.org/packages/Carbunqlex/)\n[![Carbunqlex](https://img.shields.io/nuget/dt/Carbunqlex.svg)](https://www.nuget.org/packages/Carbunqlex/)\n\n## 🚀 Overview\n\n**CarbunqleX** enhances the reusability and maintainability of raw SQL queries by deeply analyzing their Abstract Syntax Tree (AST). This allows for powerful transformations while preserving query semantics. With CarbunqleX, you can:\n\n- Modify selection columns\n- Inject `JOIN` and `WHERE` conditions dynamically\n- Transform queries into different SQL statements (`CREATE TABLE AS`, `INSERT INTO`, `UPDATE`, `DELETE`)\n\n## 💡 Key Features\n\n### Advanced CTE Handling\n\nCarbunqleX offers **flexible Common Table Expression (CTE) processing**. Traditionally, CTEs exist only within the `WITH` clause and cannot be referenced in `WHERE` or `JOIN` conditions. However, CarbunqleX detects existing CTEs and **lifts them to the top level**, making them accessible in places where they would otherwise be restricted. This enables highly flexible query modifications.\n\n### Intelligent Search Condition Injection\n\nUnlike conventional SQL libraries, CarbunqleX automatically determines the most appropriate insertion point for search conditions, even within complex queries involving subqueries and CTEs. This ensures optimal filtering while preserving query integrity. For example, when dealing with `GROUP BY`, conditions are inserted **before** aggregation to ensure correctness.\n\n### Lightweight and Easy to Use\n\n- **Minimal dependencies** – Works directly with raw SQL\n- **No special setup or DBMS required** – Purely operates on query strings\n- **Seamless ORM integration** – Works alongside existing ORM frameworks\n\n## 📦 Installation\n\n[Carbunqlex](https://www.nuget.org/packages/Carbunqlex/) can be installed from NuGet. To install using the package manager, use the following command:\n\n```sh\nNuGet\\Install-Package Carbunqlex\n```\n\n## 📖 Documentation\n\nThe complete code for the sample used here can be found at [Sample.csproj](https://github.com/mk3008/CarbunqleX/tree/91c752ba382df24238451bad0416bfd4f80bbf82/demo/Sample)\n\n### **1. Parsing a SQL Query**\n\nLet's start by parsing a simple SQL query into an AST using `QueryAstParser.Parse`. We will then convert it back to SQL with `ToSql` and inspect its structure using `ToTreeString`.\n\n```csharp\nusing Carbunqlex;\nusing Carbunqlex.Parsing;\n\nvar sql = \"SELECT a.table_a_id, a.value FROM table_a AS a\";\nvar query = QueryAstParser.Parse(sql);\n\n// Convert back to SQL\nConsole.WriteLine(\"* SQL\");\nConsole.WriteLine(query.ToSql());\n\n// View AST structure (useful for debugging)\nConsole.WriteLine(\"* AST\");\nConsole.WriteLine(query.ToTreeString());\n```\n\n#### 🔍 Expected SQL Output\n\n```sql\nSELECT a.table_a_id, a.value FROM table_a AS a\n```\n\nThis makes it easy to convert between them.\n\n### **2. Modifying the WHERE Clause**\n\nNow, let's modify the query by injecting a `WHERE` condition.\n\n```csharp\nvar query = QueryAstParser.Parse(\"SELECT a.table_a_id, a.value FROM table_a AS a\");\n\n// Inject a filter condition\nquery.Where(\"value\", w =\u003e w.Equal(1));\n\nConsole.WriteLine(query.ToSql());\n```\n\n#### 🔍 Expected SQL Output\n\n```sql\nSELECT a.table_a_id, a.value\nFROM table_a AS a\nWHERE a.value = 1;\n```\n\nCarbunqleX allows you to inject conditions while still maintaining the integrity of your SQL.\n\n### **3. Handling CTEs and Subqueries**\n\nLet's try to insert a `WHERE` condition into a query that contains a **CTE and a subquery**.\n\n```csharp\nvar query = QueryAstParser.Parse(\"\"\"\n    WITH regional_sales AS (\n        SELECT orders.region, SUM(orders.amount) AS total_sales\n        FROM orders\n        GROUP BY orders.region\n    ), top_regions AS (\n        SELECT rs.region\n        FROM regional_sales rs\n        WHERE rs.total_sales \u003e (SELECT SUM(x.total_sales)/10 FROM regional_sales x)\n    )\n    SELECT orders.region, orders.product, SUM(orders.quantity) AS product_units, SUM(orders.amount) AS product_sales\n    FROM orders\n    WHERE orders.region IN (SELECT x.region FROM top_regions x)\n    GROUP BY orders.region, orders.product\n\"\"\");\n\nquery.Where(\"region\", w =\u003e w.Equal(\"'east'\"));\n```\n\n#### 🔍 Modified SQL Output\n\n```sql\nWITH regional_sales AS (\n    SELECT orders.region, SUM(orders.amount) AS total_sales\n    FROM orders\n    WHERE orders.region = 'east'\n    GROUP BY orders.region\n),\n top_regions AS (\n    SELECT rs.region\n    FROM regional_sales rs\n    WHERE rs.total_sales \u003e (SELECT SUM(x.total_sales)/10 FROM regional_sales x)\n)\nSELECT orders.region, orders.product, SUM(orders.quantity) AS product_units, SUM(orders.amount) AS product_sales\nFROM orders\nWHERE orders.region IN (SELECT x.region FROM top_regions x)\nGROUP BY orders.region, orders.product;\n```\n\nCarbunqleX will **intelligently place the condition in the deepest related query**. It will also **dynamically merge CTEs**.\n\n### **4. Standardizing filtering**\n\nNext, we will introduce a more advanced use case that dynamically filters data based on user permissions. We define the areas that users can access as reusable functions.\n\n#### 🔧 Define a Subquery Function\n\n```csharp\nprivate QueryNode BuildRegionScalarQueryByUser(int userId)\n{\n    return QueryAstParser.Parse(\"\"\"\n        WITH user_permissions AS (\n            SELECT rrp.region\n            FROM region_reference_permission rrp\n            WHERE rrp.user_id = :user_id\n        )\n        SELECT up.region FROM user_permissions up\n    \"\"\")\n    .AddParameter(\":user_id\", userId);\n}\n```\n\n#### 🔍 Apply the Function in a Query\n\n```csharp\nvar query = QueryAstParser.Parse(\"...\");\nquery.Where(\"region\", w =\u003e w.Exists(BuildRegionScalarQueryByUser(1)));\n```\n\n#### 🔍 Expected SQL Output\n\n```sql\nWITH user_permissions AS (\n    SELECT rrp.region\n    FROM region_reference_permission AS rrp\n    WHERE rrp.user_id = :user_id\n), regional_sales AS (\n    SELECT orders.region, SUM(orders.amount) AS total_sales\n    FROM orders\n    WHERE EXISTS (\n        SELECT * \n        FROM (SELECT up.region FROM user_permissions AS up) AS x \n        WHERE orders.region = x.region\n    )\n    GROUP BY orders.region\n), top_regions AS (\n    SELECT rs.region\n    FROM regional_sales AS rs\n    WHERE rs.total_sales \u003e (SELECT SUM(x.total_sales) / 10 FROM regional_sales AS x)\n)\nSELECT orders.region, orders.product, SUM(orders.quantity) AS product_units, SUM(orders.amount) AS product_sales\nFROM orders\nWHERE orders.region IN (SELECT x.region FROM top_regions AS x)\nGROUP BY orders.region, orders.product\n```\n\nBy making filtering a function, we can express queries that are **highly maintainable and versatile**.\n\n### **5. Modify columns** \n\nThis feature is useful for enforcing constraints such as **closing date control in accounting** by ensuring a column value does not fall below a specified threshold.  \n\n```csharp\nvar query = QueryAstParser.Parse(\"SELECT s.sale_date, s.sales_amount FROM sales AS s\");\n\n// Ensure sale_date is at least '2024-01-01'\nquery.ModifyColumn(\"sale_date\", c =\u003e c.Greatest(new DateTime(2024, 1, 1)));\n\nConsole.WriteLine(query.ToSql());\n```\n\n#### 🔍 Expected SQL Output  \n\n```sql\nSELECT GREATEST(s.sale_date, '2024-01-01 00:00:00') AS sale_date, s.sales_amount \nFROM sales AS s;\n```\n\nIn this way, column processing can be made common.\n\n### **6. Manage UNION queries as modular components**\n\nThis approach allows you to manage `UNION` queries as separate components, improving maintainability and modularity.\n\n```csharp\nvar query1 = QueryAstParser.Parse(\"SELECT id FROM table_a\");\nvar query2 = QueryAstParser.Parse(\"SELECT id FROM table_b\");\n\n// Create a UNION ALL query and wrap it as a distinct subquery\nvar distinctQuery = query1.UnionAll(query2).ToSubQuery().Distinct();\n\nConsole.WriteLine(distinctQuery.ToSql());\n```\n\n#### 🔍 Expected SQL Output  \n\n```sql\nSELECT DISTINCT * FROM (SELECT id FROM table_a UNION ALL SELECT id FROM table_b) AS d;\n```\n\nNow managing huge union queries is not scary.\n\n### **7. Filtering using outer joins**\n\nYou can also dynamically insert outer join conditions to perform filtering.\n\n```csharp\nvar query = QueryAstParser.Parse(\"\"\"  \n  WITH regional_sales AS (  \n      SELECT orders.region, SUM(orders.amount) AS total_sales  \n      FROM orders  \n      GROUP BY orders.region  \n  ), top_regions AS (  \n      SELECT rs.region  \n      FROM regional_sales rs  \n      WHERE rs.total_sales \u003e (SELECT SUM(x.total_sales)/10 FROM regional_sales x)  \n  )  \n  SELECT orders.region,  \n         orders.product,  \n         SUM(orders.quantity) AS product_units,  \n         SUM(orders.amount) AS product_sales  \n  FROM orders   \n  WHERE orders.region IN (SELECT x.region FROM top_regions x)  \n  GROUP BY orders.region, orders.product  \n\"\"\");\n\n// Set isCurrentOnly: false to use the join as a filter condition  \nquery.From(\"region\", isCurrentOnly: false, static from =\u003e\n{\n    from.LeftJoin(\"top_regions\", \"tp\");\n    from.EditQuery(q =\u003e\n    {\n        q.Where(\"tp.region is null\");\n    });\n});\n\n// left join top_regions as tp on orders.region = tp.region where tp.region is null  \nvar expected = \"with regional_sales as (select orders.region, SUM(orders.amount) as total_sales from orders left join top_regions as tp on orders.region = tp.region where tp.region is null group by orders.region), top_regions as (select rs.region from regional_sales as rs where rs.total_sales \u003e (select SUM(x.total_sales) / 10 from regional_sales as x)) select orders.region, orders.product, SUM(orders.quantity) as product_units, SUM(orders.amount) as product_sales from orders where orders.region in (select x.region from top_regions as x) group by orders.region, orders.product\";\n```\n\n### **8. Create a table from a select query**\n\nYou can convert a select query into a `CREATE TABLE` statement. This is very useful when you want to create a new table based on the results of a query.\n\n```csharp\nvar query = QueryAstParser.Parse(\"SELECT a.table_a_id, 1 AS value FROM table_a AS a\");\n\n// Generate a CREATE TABLE query, specifying that the table is temporary\nvar createTableQuery = query.ToCreateTableQuery(\"table_b\", isTemporary: true);\n\n// Print the generated SQL query\nConsole.WriteLine(createTableQuery.ToSql());\n```\n\n#### 🔍 Expected SQL output\n\n```sql\nCREATE TEMPORARY TABLE table_b AS SELECT a.table_a_id, 1 AS value FROM table_a AS a;\n```\n\n### 9. Manage Update Queries with Select Queries\n\nThe effects of insert, update, and delete queries can only be seen after they are executed, making it difficult to preview the expected results in advance.\n\nCarbunqleX allows you to express these queries as select queries. Select queries simplify the debugging and validation process by allowing you to preview changes without actually modifying tables.\n\n```csharp\nvar query = QueryAstParser.Parse(\"SELECT a.table_a_id, 1 AS value FROM table_a AS a\");\n\n// Generate an INSERT INTO query for table_b with a RETURNING clause\nvar insertTableQuery = query.ToInsertQuery(\"table_b\", hasReturning: true);\n\n// Print the generated SQL query\nConsole.WriteLine(insertTableQuery.ToSql());\n```\n\n#### 🔍 Expected SQL output\n\n```sql\nINSERT INTO table_b(table_a_id, value)\nSELECT a.table_a_id, 1 AS value FROM table_a AS a\nRETURNING *;\n```\n\nThe above example demonstrates how to express an insert query using a select query, but similar techniques can also be applied to update and delete queries.\n\nFor update queries:\n\n```csharp\nvar query = QueryAstParser.Parse(\"SELECT a.table_a_id, 1 AS value FROM table_a AS a\");\n\nvar updateQuery = query.ToUpdateQuery(\"table_b\", new[] { \"table_a_id\" });\n\nvar expected = \"UPDATE table_b SET value = q.value FROM (SELECT a.table_a_id, 1 AS value FROM table_a AS a) AS q WHERE table_b.table_a_id = q.table_a_id\";\n```\n\nFor delete queries:\n\n```csharp\nvar query = QueryAstParser.Parse(\"SELECT a.table_a_id, 1 AS value FROM table_a AS a\");\n\nvar deleteQuery = query.ToDeleteQuery(\"table_b\", new[] { \"table_a_id\" });\n\nvar expected = \"DELETE FROM table_b WHERE table_b.table_a_id IN (SELECT q.table_a_id FROM (SELECT a.table_a_id, 1 AS value FROM table_a AS a) AS q)\";\n```\n\n### 10. Converting a Query to Return JSON (Postgres-only) ver 0.0.3 or later\n\nIn PostgreSQL, you can transform a query to return JSON using functions like `json_build_object` and `row_to_json`.\n\n```csharp\nvar query = QueryAstParser.Parse(\"\"\"\n    SELECT \n        posts.post_id, \n        posts.title, \n        posts.content, \n        posts.created_at, \n        users.user_id, \n        users.name AS user_name, \n        blogs.blog_id, \n        blogs.name AS blog_name, \n        organizations.organization_id, \n        organizations.name AS organization_name\n    FROM posts\n    INNER JOIN users ON posts.user_id = users.user_id\n    INNER JOIN blogs ON posts.blog_id = blogs.blog_id\n    INNER JOIN organizations ON blogs.organization_id = organizations.organization_id\n\"\"\");\n\nquery.Where(\"post_id\", action: x =\u003e x.Equal(\":post_id\"))\n    .NormalizeSelectClause()\n    .ToPostgresJsonQuery(x =\u003e\n    {\n        return x.Serialize(datasource: \"posts\", jsonKey: \"post\", parent: static x =\u003e\n        {\n            return x.Serialize(datasource: \"users\", jsonKey: \"user\")\n                .Serialize(datasource: \"blogs\", jsonKey: \"blog\", parent: static x =\u003e\n                {\n                    return x.Serialize(datasource: \"organizations\", jsonKey: \"organization\");\n                });\n        });\n    });\n```\n\n#### 🔍 Expected SQL output\n\n```sql\nWITH\n    __json AS (\n        SELECT\n            posts.post_id AS posts__post_id,\n            posts.title AS posts__title,\n            posts.content AS posts__content,\n            posts.created_at AS posts__created_at,\n            users.user_id AS users__user_id,\n            users.name AS users__user_name,\n            blogs.blog_id AS blogs__blog_id,\n            blogs.name AS blogs__blog_name,\n            organizations.organization_id AS organizations__organization_id,\n            organizations.name AS organizations__organization_name\n        FROM\n            posts\n            INNER JOIN users ON posts.user_id = users.user_id\n            INNER JOIN blogs ON posts.blog_id = blogs.blog_id\n            INNER JOIN organizations ON blogs.organization_id = organizations.organization_id\n        WHERE\n            posts.post_id = :post_id\n    )\nSELECT\n    ROW_TO_JSON(d)\nFROM\n    (\n        SELECT\n            JSON_BUILD_OBJECT(\n                'post_id', __json.posts__post_id,\n                'title', __json.posts__title,\n                'content', __json.posts__content,\n                'created_at', __json.posts__created_at,\n                'user', JSON_BUILD_OBJECT(\n                    'user_id', __json.users__user_id,\n                    'user_name', __json.users__user_name\n                ),\n                'blog', JSON_BUILD_OBJECT(\n                    'blog_id', __json.blogs__blog_id,\n                    'blog_name', __json.blogs__blog_name,\n                    'organization', JSON_BUILD_OBJECT(\n                        'organization_id', __json.organizations__organization_id,\n                        'organization_name', __json.organizations__organization_name\n                    )\n                )\n            ) AS \"post\"\n        FROM\n            __json\n    ) AS d\nLIMIT\n    1\n```\n\n#### 🔍 Query Output\n\n```json\n{\n    \"post\": {\n        \"post_id\": 1,\n        \"title\": \"Understanding AI\",\n        \"content\": \"This is a post about AI.\",\n        \"created_at\": \"2025-02-18T20:25:21.974106\",\n        \"user\": {\n            \"user_id\": 1,\n            \"user_name\": \"Alice\"\n        },\n        \"blog\": {\n            \"blog_id\": 1,\n            \"blog_name\": \"AI Insights\",\n            \"organization\": {\n                \"organization_id\": 1,\n                \"organization_name\": \"Tech Corp\"\n            }\n        }\n    }\n}\n```\n\n### 11. Converting a Query to Return JSON Array (Postgres-only) ver 0.0.3 or later\n\nYou can also get a JSON array. Since the results are aggregated on the DB server, there is no need to loop through the DataReader. There is also no need to issue multiple queries.\n\n```csharp\nvar query = QueryAstParser.Parse(\"\"\"\n    SELECT \n        posts.post_id, \n        posts.title, \n        posts.content, \n        posts.created_at, \n        users.user_id, \n        users.name AS user_name, \n        blogs.blog_id, \n        blogs.name AS blog_name, \n        organizations.organization_id, \n        organizations.name AS organization_name\n    FROM posts\n    INNER JOIN users ON posts.user_id = users.user_id\n    INNER JOIN blogs ON posts.blog_id = blogs.blog_id\n    INNER JOIN organizations ON blogs.organization_id = organizations.organization_id\n\"\"\");\n\nquery.Where(\"user_id\", action: x =\u003e x.Equal(\":user_id\"))\n    .NormalizeSelectClause()\n    .ToPostgresJsonQuery(x =\u003e\n    {\n        return x.Serialize(datasource: \"users\", jsonKey: \"user\", parent: static x =\u003e\n        {\n            return x.SerializeArray(datasource: \"posts\", jsonKey: \"posts\", parent: static x =\u003e\n            {\n                return x.Serialize(datasource: \"blogs\", jsonKey: \"blog\", parent: static x =\u003e\n                {\n                    return x.Serialize(datasource: \"organizations\", jsonKey: \"organization\");\n                });\n            });\n        });\n    });\n```\n\n#### 🔍 Expected SQL output\n\n```sql\nWITH\n    __json AS (\n        SELECT\n            posts.post_id AS posts__post_id,\n            posts.title AS posts__title,\n            posts.content AS posts__content,\n            posts.created_at AS posts__created_at,\n            users.user_id AS users__user_id,\n            users.name AS users__user_name,\n            blogs.blog_id AS blogs__blog_id,\n            blogs.name AS blogs__blog_name,\n            organizations.organization_id AS organizations__organization_id,\n            organizations.name AS organizations__organization_name\n        FROM\n            posts\n            INNER JOIN users ON posts.user_id = users.user_id\n            INNER JOIN blogs ON posts.blog_id = blogs.blog_id\n            INNER JOIN organizations ON blogs.organization_id = organizations.organization_id\n        WHERE\n            users.user_id = :user_id\n    ),\n    __json_posts AS (\n        SELECT\n            __json.users__user_id,\n            __json.users__user_name,\n            JSON_AGG(JSON_BUILD_OBJECT('post_id', __json.posts__post_id, 'title', __json.posts__title, 'content', __json.posts__content, 'created_at', __json.posts__created_at, 'blog', JSON_BUILD_OBJECT('blog_id', __json.blogs__blog_id, 'blog_name', __json.blogs__blog_name, 'organization', JSON_BUILD_OBJECT('organization_id', __json.organizations__organization_id, 'organization_name', __json.organizations__organization_name)))) AS users__posts\n        FROM\n            __json\n        GROUP BY\n            __json.users__user_id,\n            __json.users__user_name\n    )\nSELECT\n    ROW_TO_JSON(d)\nFROM\n    (\n        SELECT\n            JSON_BUILD_OBJECT(\n                'user_id', __json_posts.users__user_id,\n                'user_name', __json_posts.users__user_name,\n                'posts', __json_posts.users__posts\n            ) AS \"user\"\n        FROM\n            __json_posts\n    ) AS d\nLIMIT\n    1\n```\n\n#### 🔍 Query Output\n\n```json\n{\n  \"user\": {\n    \"user_id\": 1,\n    \"user_name\": \"Alice\",\n    \"posts\": [\n      {\n        \"post_id\": 9,\n        \"title\": \"Understanding AI\",\n        \"content\": \"This is a post about AI.\",\n        \"created_at\": \"2025-02-18T20:25:21.974106\",\n        \"blog\": {\n          \"blog_id\": 1,\n          \"blog_name\": \"AI Insights\",\n          \"organization\": {\n            \"organization_id\": 1,\n            \"organization_name\": \"Tech Corp\"\n          }\n        }\n      },\n      {\n        \"post_id\": 11,\n        \"title\": \"Understanding AI\",\n        \"content\": \"This is a post about AI.\",\n        \"created_at\": \"2025-03-07T17:53:49.168646\",\n        \"blog\": {\n          \"blog_id\": 1,\n          \"blog_name\": \"AI Insights\",\n          \"organization\": {\n            \"organization_id\": 1,\n            \"organization_name\": \"Tech Corp\"\n          }\n        }\n      }\n    ]\n  }\n}\n```\n\n### To improve maintainability\n\nDefining parent-child relationships using local functions makes them easier to maintain.\n\n![image](https://github.com/user-attachments/assets/1a06a0d3-4e05-4c38-bd53-7297fb51131b)\n\n## 📌 Conclusion\n\nCarbunqleX makes raw SQL **more maintainable, reusable, and dynamically modifiable** without sacrificing performance. Its AST-based transformations provide a powerful way to manipulate queries at scale, making it an essential tool for advanced SQL users.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmk3008%2Fcarbunqlex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmk3008%2Fcarbunqlex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmk3008%2Fcarbunqlex/lists"}