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>
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:
:parametersyntax (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
- Documentation Generation: Automatically generate documentation for complex SQL queries
- Code Review: Visualize query structure for easier code reviews
- Learning Tool: Help developers understand complex SQL queries through visual diagrams
- Query Analysis: Analyze query patterns and structures
- 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