Files
sql-utilities/src/Strata.SqlTools.Markdown
Thom LambandClaude Opus 4.7 5202d93e8e
SonarQube Analysis / sonarqube (pull_request) Successful in 3m30s
chore(sonar)!: mark public Markdown generator methods static (CA1822)
Three public methods on the SqlServer-namespaced Markdown generators no
longer touch instance state and now carry the `static` keyword:

- `Markdown.SqlServer.QueryBreakdownGenerator.GenerateMermaidDiagram(QueryBreakdown, string?)`
- `Markdown.SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(ISqlBreakdown, string?)`
- `Markdown.SqlServer.SqlStatementGenerator.GenerateEntityRelationshipDiagram(IEnumerable<string>, string?)`

Plus one private bonus the analyzer caught on the same pass:
- `LinqExpressionVisitor.ExtractSelectExpression` → static (non-breaking).

Internal callers in the Snowflake/LinqToSql/PostgreSql wrapper classes
and in the test fixtures are updated to the type-name form
(`SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(...)`).
The wrappers retain their `_baseGenerator` field for now even though it
is no longer used — that S4487 / unused-field cleanup is its own commit.

BREAKING CHANGE: External NuGet consumers calling
`generatorInstance.GenerateMermaidDiagram(...)`,
`generatorInstance.GenerateSequenceDiagram(...)`, or
`generatorInstance.GenerateEntityRelationshipDiagram(...)` on the
SqlServer-namespaced generators must switch to type-name form, e.g.
`Markdown.SqlServer.SqlStatementGenerator.GenerateSequenceDiagram(...)`.
Calls through the Snowflake / LinqToSql / PostgreSql wrapper classes are
unaffected at the call site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:22:27 -05:00
..

Strata.SqlTools.Markdown

Markdown documentation generation for SQL queries and expressions from Strata.SqlTools.

Overview

This library provides tools to generate markdown documentation and Mermaid diagrams from SQL query breakdowns and expression trees. It's designed to help document SQL queries and their structure in a human-readable format.

Features

SqlServer Folder - Mermaid Diagram Generation

QueryBreakdownGenerator

Generates Mermaid flowchart diagrams from SQL QueryBreakdown objects, visualizing:

  • WITH clauses (Common Table Expressions)
  • SELECT, FROM, WHERE clauses
  • GROUP BY, HAVING, ORDER BY clauses
  • Setup and Finish clauses

Example Usage:

using Strata.SqlTools.Breakdowns.SqlServer;
using Strata.SqlTools.Markdown.SqlServer;

var query = QueryBreakdown.Parse(@"
    SELECT u.ID, u.Name, COUNT(o.OrderID) as OrderCount
    FROM Users u
    JOIN Orders o ON u.ID = o.UserID
    WHERE u.Active = 1
    GROUP BY u.ID, u.Name
    HAVING COUNT(o.OrderID) > 5
    ORDER BY OrderCount DESC
");

var generator = new QueryBreakdownGenerator();
string markdown = generator.GenerateMermaidDiagram(query, "User Orders Query");

// Output the markdown to a file or display
Console.WriteLine(markdown);

SqlStatementGenerator

Generates Mermaid sequence diagrams showing SQL statement execution flow and entity-relationship diagrams.

Example Usage:

var seqGenerator = new SqlStatementGenerator();
string sequenceDiagram = seqGenerator.GenerateSequenceDiagram(sqlBreakdown, "Query Execution Flow");

// Generate ER diagram for tables
var tables = new[] { "Users", "Orders", "OrderDetails" };
string erDiagram = seqGenerator.GenerateEntityRelationshipDiagram(tables, "Database Schema");

Snowflake Folder - Snowflake SQL Support

The library fully supports Snowflake SQL syntax, including Snowflake-specific features like:

  • :parameter syntax (in addition to @parameter)
  • Double-quoted identifiers "identifier"
  • QUALIFY clauses for window functions
  • Type casting with :: operator
  • JSON path notation with : accessor

QueryBreakdownGenerator (Snowflake)

Generates Mermaid flowchart diagrams from Snowflake QueryBreakdown objects.

Example Usage:

using Strata.SqlTools.Breakdowns.Snowflake;
using Strata.SqlTools.Markdown.Snowflake;

// Parse Snowflake SQL with :parameter syntax
var query = QueryBreakdown.Parse(@"
    WITH ACTIVE_USERS AS (
        SELECT USER_ID, USER_NAME, EMAIL
        FROM USERS
        WHERE STATUS = :status AND REGION = :region
    )
    SELECT
        AU.USER_ID,
        AU.USER_NAME,
        COUNT(O.ORDER_ID) AS ORDER_COUNT,
        SUM(O.AMOUNT):: DECIMAL(10,2) AS TOTAL_AMOUNT
    FROM ACTIVE_USERS AU
    LEFT JOIN ORDERS O ON AU.USER_ID = O.USER_ID
    WHERE O.ORDER_DATE >= :startDate
    GROUP BY AU.USER_ID, AU.USER_NAME
    HAVING COUNT(O.ORDER_ID) > 0
    ORDER BY TOTAL_AMOUNT DESC
", isMicrosoftSql: false);

var generator = new QueryBreakdownGenerator();
string markdown = generator.GenerateMermaidDiagram(query, "Snowflake User Orders Analysis");

Console.WriteLine(markdown);

SqlStatementGenerator (Snowflake)

Generates sequence and ER diagrams for Snowflake SQL statements.

Example Usage:

var seqGenerator = new SqlStatementGenerator();

// Generate sequence diagram for Snowflake query flow
string sequenceDiagram = seqGenerator.GenerateSequenceDiagram(snowflakeQuery, "Snowflake Query Flow");

// Generate ER diagram for Snowflake tables (typically uppercase)
var tables = new[] { "CUSTOMERS", "ORDERS", "ORDER_ITEMS", "PRODUCTS" };
string erDiagram = seqGenerator.GenerateEntityRelationshipDiagram(tables, "Snowflake Schema");

Expressions Folder - Expression Documentation

ExpressionGenerator

Generates comprehensive markdown documentation for SQL expression trees with:

  • Hierarchical structure visualization
  • Type information
  • Mermaid tree diagrams
  • Mathematical notation using LaTeX (GitHub compatible)

Example Usage:

using Strata.SqlTools.SqlBreakdown.Expressions;
using Strata.SqlTools.Markdown.Expressions;

// Build an expression
Expression quantity = new ColumnExpression<TableSource>(tableSource, "Quantity");
Expression unitPrice = new ColumnExpression<TableSource>(tableSource, "UnitPrice");
Expression discount = new ColumnExpression<TableSource>(tableSource, "Discount");

var totalExpression = (quantity * unitPrice) * (1 - discount);

var generator = new ExpressionGenerator();
string markdown = generator.GenerateMarkdown(totalExpression, "Order Line Total Calculation");

// Output includes:
// - Expression structure tree
// - Type information
// - Mermaid diagram visualization
// - Mathematical expression in LaTeX format
Console.WriteLine(markdown);

// Or generate just the mathematical expression
string mathExpr = generator.GenerateMathematicalExpression(totalExpression);
// Produces: $$(Quantity \times UnitPrice) \times (1 - Discount)$$

// For inline math notation
string inlineMath = generator.GenerateMathematicalExpression(totalExpression, inline: true);
// Produces: $(Quantity \times UnitPrice) \times (1 - Discount)$

// For raw LaTeX expressions (e.g., mathematical formulas)
var cauchySchwarz = @"\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)";
string dollarFormat = generator.GenerateRawMathematicalExpression(cauchySchwarz);
// Produces: $$
//           \left( \sum_{k=1}^n a_k b_k \right)^2 \leq ...
//           $$

string mathCodeFence = generator.GenerateRawMathematicalExpression(cauchySchwarz, format: "math");
// Produces: ```math
//           \left( \sum_{k=1}^n a_k b_k \right)^2 \leq ...
//           ```

Mathematical Notation Features:

  • Arithmetic operators: +, -, × (\times), ÷ (\div), mod (\bmod)
  • Comparison operators: =, (\neq), <, >, (\leq), (\geq)
  • Logical operators: (\land), (\lor), ¬ (\neg)
  • Functions: SUM (\sum), MIN (\min), MAX (\max), |x| (ABS), (\sqrt), powers, etc.
  • Set operations: for BETWEEN and IN expressions
  • Case expressions using piecewise notation (\begin{cases})

SimpleExpressionGenerator

Generates simplified, readable markdown documentation for expressions with:

  • SQL representation
  • Type information
  • Human-readable descriptions
  • Comparison tables for multiple expressions
  • Bulleted lists

Example Usage:

var simpleGenerator = new SimpleExpressionGenerator();

// Generate simple markdown for a single expression
string simpleMarkdown = simpleGenerator.GenerateMarkdown(expression, "Price Filter");

// Generate comparison table for multiple expressions
var expressions = new Dictionary<string, Expression>
{
    ["Basic Filter"] = status == "Active",
    ["Date Filter"] = orderDate > new DateTime(2024, 1, 1),
    ["Complex Filter"] = (quantity > 10) & (price < 100)
};

string comparisonTable = simpleGenerator.GenerateComparisonTable(expressions, "Filter Expressions");

// Generate bullet list
var expressionList = new List<Expression> { expr1, expr2, expr3 };
string bulletList = simpleGenerator.GenerateBulletList(expressionList, "Common Filters");

Installation

Add a reference to this project in your .csproj file:

<ItemGroup>
  <ProjectReference Include="..\Strata.SqlTools.Markdown\Strata.SqlTools.Markdown.csproj" />
</ItemGroup>

Dependencies

  • Strata.SqlTools - Core SQL utilities library
  • Strata.SqlTools.SqlServer - SQL Server specific implementations
  • Strata.SqlTools.Snowflake - Snowflake specific implementations
  • .NET 9.0 or later

Use Cases

  1. Documentation Generation: Automatically generate documentation for complex SQL queries
  2. Code Review: Visualize query structure for easier code reviews
  3. Learning Tool: Help developers understand complex SQL queries through visual diagrams
  4. Query Analysis: Analyze query patterns and structures
  5. API Documentation: Document SQL expressions used in query builders

Output Examples

Mermaid Flowchart

The QueryBreakdownGenerator produces flowcharts like:

flowchart TD
    Start([Query Start]) --> Node1
    Node1["SELECT<br/>u.ID, u.Name, COUNT(o.OrderID)"]
    Node1 --> Node2
    Node2["FROM<br/>Users u JOIN Orders o"]
    Node2 --> Node3
    Node3{"WHERE<br/>u.Active = 1"}
    Node3 --> Node4
    Node4["GROUP BY<br/>u.ID, u.Name"]
    Node4 --> Node5
    Node5{"HAVING<br/>COUNT(o.OrderID) > 5"}
    Node5 --> Node6
    Node6["ORDER BY<br/>OrderCount DESC"]
    Node6 --> End([Query End])

Expression Documentation

Comprehensive Expression Markdown (ExpressionGenerator)

The ExpressionGenerator produces detailed documentation including structure, type info, diagrams, and mathematical notation:

# Order Line Total Calculation

## Expression Structure
- **Type**: ArithmeticExpression
- **Operator**: Multiply (*)
- **Left Expression**: ArithmeticExpression (Quantity * UnitPrice)
- **Right Expression**: ArithmeticExpression (1 - Discount)

## Mermaid Diagram
```mermaid
graph TD
    Root["* (Multiply)"]
    Root --> Left["* (Multiply)"]
    Root --> Right["- (Subtract)"]
    Left --> LeftLeft["Quantity (Column)"]
    Left --> LeftRight["UnitPrice (Column)"]
    Right --> RightLeft["1 (Constant)"]
    Right --> RightRight["Discount (Column)"]

Mathematical Expression

(Quantity \times UnitPrice) \times (1 - Discount)

#### Simple Expression Markdown (SimpleExpressionGenerator)

The `SimpleExpressionGenerator` produces concise, readable output:

**Single Expression:**
```markdown
# Price Filter

**Expression Type**: ComparisonExpression

**SQL Representation**:
```sql
UnitPrice < 100

Description: Filters records where UnitPrice is less than 100


**Comparison Table:**
```markdown
# Filter Expressions Comparison

| Name | Expression Type | SQL Representation |
|------|----------------|-------------------|
| Basic Filter | ComparisonExpression | `Status = 'Active'` |
| Date Filter | ComparisonExpression | `OrderDate > '2024-01-01'` |
| Complex Filter | LogicalExpression | `(Quantity > 10) AND (Price < 100)` |

Bullet List:

# Common Filters

- **Status = 'Active'** (ComparisonExpression)
- **OrderDate > '2024-01-01'** (ComparisonExpression)
- **(Quantity > 10) AND (Price < 100)** (LogicalExpression)

Contributing

Contributions are welcome! Please ensure all code follows the existing patterns and includes appropriate documentation.

License

MIT License - Copyright © Strata Decision Technology 2024-2026