Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions LIBRARY_GUIDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# PartiQL Graphviz Visualization Library Maintenance Guide

This guide provides information for the PartiQL team on how to maintain and extend the PartiQL Graphviz visualization library.

## How to Add New Nodes

When adding support for new AST node types, follow these steps:

1. **Identify the node type**: Determine which PartiQL AST node type you need to add support for.

2. **Create a conversion method**: Add a new method following the naming pattern `convert[NodeType]ToNode()`. For example:

```java
private Node convert[NewNodeType]ToNode([NewNodeType] newNode) {
Node newNodeNode = createNode(newNode).with(label("[NewNodeType]"));

// Add links to child nodes
// For each child node or property that should be visualized:
newNodeNode = newNodeNode.link(to(convertChildToNode(newNode.getChild())).with(Label.of("childName")));

return newNodeNode;
}
```

3. **Update the parent method**: Add a new case to the appropriate switch statement in the parent method that handles this type of node. For example, if adding a new expression type:

```java
private Node convertExprToNode(Expr expr) {
return switch (expr) {
// Existing cases...
case [NewExprType] newExprType -> convert[NewExprType]ToNode(newExprType);
default -> throw new IllegalArgumentException("Unsupported expression: " + expr);
};
}
```

4. **Test the visualization**: Create a test query that uses the new node type and verify that it renders correctly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should also include a reference for where to put the test and how to work w/ the snapshot testing


## How to Debug

When debugging visualization issues:

1. **Start with simple queries**: Begin with minimal queries that use the specific node type you're working with.

2. **Use the debugger**: Step through the code using your IDE's debugger to inspect the structure of both the AST and the resulting Graphviz graph.

3. **Set breakpoints**: Place breakpoints in key methods like `convertQueryToGraph()` to examine how nodes are being processed.

4. **Inspect object structures**: Use the debugger's variable inspection features to examine the properties of AST nodes and the corresponding Graphviz nodes being created.

5. **Watch the graph construction**: Step through the code to see how nodes are connected with edges and how the graph is built incrementally.

6. **Start with simple queries**: Begin with minimal queries that use the specific node type you're working with.

7. **Incremental testing**: Add complexity to your test queries gradually to isolate issues.

8. **Add debug labels**: Temporarily add more detailed labels to nodes to show internal state:

```java
// Instead of just the node type
Node node = createNode(expr).with(label("ExprOperator: " + expr.getSymbol() + " [details: " + additionalInfo + "]"));
```



## How to Think About Visualizing Nodes

When designing visualizations for AST nodes:

1. **Hierarchical structure**: Visualize the AST as a top-down hierarchy, with the root node at the top.

2. **Node labeling**: Use clear, concise labels that convey the node's type and essential information.

3. **Edge labeling**: Label edges to show the relationship between nodes (e.g., "lhs", "rhs", "condition").

4. **Visual consistency**: Maintain consistent styling for similar node types.

5. **Information density**: Balance between showing enough information and avoiding visual clutter.

6. **Node grouping**: Consider grouping related nodes (e.g., all items in a SELECT list) under a common parent.

7. **Special characters**: Remember to escape special characters in labels using the `escapeGraphvizLabel()` method.

## Common Graphviz Classes and Functions

### Core Classes

- **`Graph`**: Represents the entire graph structure.
```java
Graph g = graph("Ast Graph").directed();
```

- **`Node`**: Represents a node in the graph.
```java
Node node = node("nodeName").with(label("Node Label"));
```

### Node Creation and Styling

- **`createNode(AstNode ast)`**: Creates a node with a unique identifier based on the AST node's class name.
```java
Node node = createNode(astNode);
```

- **`label(String text)`**: Sets the display label for a node.
```java
node.with(label("Label Text"));
```

- **`Color`**: Defines colors for nodes and edges.
```java
node.with(Color.RED);
```

- **`Style`**: Sets styling attributes for nodes.
```java
node.with(Style.FILLED, Style.lineWidth(2));
```

### Edge Creation and Styling

- **`link(Node target)`**: Creates an edge from one node to another.
```java
sourceNode.link(targetNode);
```

- **`to(Node target)`**: Used with `link()` to create edges with labels.
```java
sourceNode.link(to(targetNode).with(Label.of("edgeLabel")));
```

### Graph Rendering

- **`convertGraphToDot(Graph graph, String path)`**: Saves the graph as a DOT file.
```java
astToGraph.convertGraphToDot(graph, "output.dot");
```

- **`convertDotToPng(Graph graph, String path, double scale)`**: Renders the graph as a PNG image.
```java
astToGraph.convertDotToPng(graph, "output.png", 2.0);
```

- **`convertDotToSvg(Graph graph, String path, double scale)`**: Renders the graph as an SVG image.
```java
astToGraph.convertDotToSvg(graph, "output.svg", 2.0);
```

### Utility Functions

- **`escapeGraphvizLabel(String text)`**: Escapes special characters in labels.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can provide some rationale that graphviz labels need to escape special characters

```java
String safeLabel = escapeGraphvizLabel("<complex>label");
```

- **`getIdentifierString(Identifier.Simple simple)`**: Formats identifiers with appropriate quoting.
```java
String idStr = getIdentifierString(identifier);
```

## Best Practices

1. **Maintain consistent styling**: Use the predefined color and style constants.

2. **Handle all node types**: Ensure switch statements have cases for all possible node types.

3. **Add detailed documentation**: Document new methods with JavaDoc comments.

4. **Test with complex queries**: Verify that visualizations work correctly with complex, nested queries.

5. **Consider performance**: For very large ASTs, consider optimizations to improve rendering speed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably too vague for a suggestion. Think we can just opt to remove it.


6. **Update tests**: When adding new node types, add corresponding test cases.
44 changes: 42 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Graphviz is a commonly used open source graph visualization library that we can




Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of scope for this PR but this file from the other unmerged PR is included. a couple ways to fix

  • create a different branch with just the LIBRARY_GUIDE.md file or
  • set the target branch for this PR to the other PR's branch (this will eliminate the redundant commits)

## Local Build
***
**Pre-requisite:**
Expand All @@ -25,6 +26,25 @@ $ git clone https://github.com/partiql/partiql-graphviz-java.git

## Usage
***
The PartiQL Graphviz visualization tool allows you to easily convert PartiQL queries into visual graph representations.

To use this functionality, first create an instance of the `AstToGraph` class.
You can then convert a PartiQL query string directly to a graph using `convertQueryToGraph(String query)`,
or if you already have a parsed AST statement, use `convertAstToGraph(Statement statement)`.

Once you have the graph, you can export it in various formats:
- Save it as a DOT file with `convertGraphToDot(graph, filePath)`
- Render it as a PNG image using `convertDotToPng(graph, filePath, scale)`
- Create an SVG with `convertDotToSvg(graph, filePath, scale)`

The `scale` parameter allows you to adjust the size of the output image.


This visualization capability is particularly useful for understanding complex query structures, debugging query issues, or educational purposes to demonstrate how PartiQL parses different query constructs.
The generated visual representation clearly shows the hierarchical structure of the query, including SELECT clauses, FROM sources, WHERE conditions, and other query components with their relationships.



### Creating and Visualizing Graphs
NOTE: All the example code is written in java
```java
Expand All @@ -41,10 +61,12 @@ public class Query {
// Define output file paths
String dotFilePath = "ast_graph.dot";
String pngFilePath = "ast_graph.png";
String svgFilePath = "ast_graph.svg";

// Save the graph in DOT and PNG formats
// Save the graph in DOT, PNG and SVG formats
astToGraph.convertGraphToDot(graph, dotFilePath);
astToGraph.convertDotToPng(graph, pngFilePath);
astToGraph.convertDotToPng(graph, pngFilePath, 2.0);
astToGraph.convertDotToSvg(graph, svgFilePath, 2.0);
}
}
```
Expand All @@ -64,8 +86,26 @@ Statement statement = parseResult.statements.get(0);
Graph graph = astToGraph.convertAstToGraph(statement);
```

### Example Query

```
Query: SELECT a,b,c FROM t WHERE d
```

### Example Graph
![img_2.png](img_2.png)



### Future Enhancements
***

TODO:
- Implement remaining AST nodes that are currently not handled by the visualization system
- Visualization of the PartiQL plan
- Introduce additional customization options for node appearance, edge styles, and color schemes
- Provide configuration parameters to control visualization verbosity, allowing for more compact graph representations when desired
- Integrate the PartiQL logo into generated visualizations

## Contributing
***
Expand Down
Loading