explain

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 2, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package explain renders Cypher execution plans as human-readable text (EXPLAIN mode) and instruments them with per-operator execution statistics (PROFILE mode).

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatReport

func FormatReport(r ProfileReport) string

FormatReport formats r as a Neo4j-style table:

+--------------------------+--------+---------+-----------+
| Operator                 |   Rows | DbHits  | Time (ms) |
+--------------------------+--------+---------+-----------+
| NodeByLabelScan          |    100 |     100 |     0.012 |
| ProduceResults           |    100 |       0 |     0.001 |
+--------------------------+--------+---------+-----------+
| Total                    |    200 |     100 |     0.013 |
+--------------------------+--------+---------+-----------+

func TextTree

func TextTree(plan ir.LogicalPlan) string

TextTree renders a physical plan in Neo4j-style columnar text:

+-------------------------+----------+----------+
| Operator                | Est.Rows | Vars     |
+-------------------------+----------+----------+
| ProduceResults          |      100 | n        |
| └─ NodeByLabelScan      |      100 | n:Person |
+-------------------------+----------+----------+

The Operator column is padded to the widest (name + tree-indent). Est.Rows comes from the [estimator] interface; nodes that do not implement it show "-". Vars lists the variables returned by ir.LogicalPlan.Vars.

Output is stable across runs: no map iteration order is relied upon. Children appear in ir.LogicalPlan.Children order.

Example

ExampleTextTree renders a logical plan as a columnar text table. The tree follows the plan's child order, so the output is stable across runs.

package main

import (
	"fmt"
	"strings"

	"github.com/FlavioCFOliveira/GoGraph/cypher/explain"
	"github.com/FlavioCFOliveira/GoGraph/cypher/ir"
)

func main() {
	plan := ir.NewProduceResults(
		[]string{"n"},
		ir.NewNodeByLabelScan("n", "Person"),
	)

	out := explain.TextTree(plan)

	// The rendered table is a fixed-width box; assert its structure rather
	// than embedding the exact padding so the example stays readable.
	fmt.Println("has header:", strings.Contains(out, "Operator") && strings.Contains(out, "Est.Rows"))
	fmt.Println("has root:", strings.Contains(out, "ProduceResults"))
	fmt.Println("has child:", strings.Contains(out, "NodeByLabelScan"))
	fmt.Println("child is nested:", strings.Contains(out, "└─ NodeByLabelScan"))
}
Output:
has header: true
has root: true
has child: true
child is nested: true

Types

type DbHitsCounter

type DbHitsCounter struct {
	// contains filtered or unexported fields
}

DbHitsCounter is a per-pipeline counter for logical storage accesses (index lookups, property reads, CSR neighbour scans). It is incremented by instrumented operator wrappers and read by the PROFILE reporter.

DbHitsCounter is safe for concurrent use.

func (*DbHitsCounter) Add

func (c *DbHitsCounter) Add(delta uint64)

Add increments the counter by delta.

func (*DbHitsCounter) Load

func (c *DbHitsCounter) Load() uint64

Load returns the current counter value.

func (*DbHitsCounter) Reset

func (c *DbHitsCounter) Reset()

Reset sets the counter back to zero.

type InstrumentedScan

type InstrumentedScan struct {
	// contains filtered or unexported fields
}

InstrumentedScan is a thin wrapper that counts dbHits per Next call. It adds 1 dbHit per row fetched from the underlying scan operator.

InstrumentedScan is NOT safe for concurrent use.

func NewInstrumentedScan

func NewInstrumentedScan(op exec.Operator, counter *DbHitsCounter) *InstrumentedScan

NewInstrumentedScan wraps op with a dbHit counter. Each successful Next call adds 1 to counter.

func (*InstrumentedScan) Close

func (s *InstrumentedScan) Close() error

Close implements exec.Operator. It delegates to the inner operator.

func (*InstrumentedScan) Init

func (s *InstrumentedScan) Init(ctx context.Context) error

Init implements exec.Operator. It delegates to the inner operator.

func (*InstrumentedScan) Next

func (s *InstrumentedScan) Next(out *exec.Row) (bool, error)

Next implements exec.Operator. It delegates to the inner operator and on a successful (true, nil) return increments the dbHits counter by 1.

type OperatorStats

type OperatorStats struct {
	// Name is the display name assigned when the operator was wrapped.
	Name string
	// Rows is the number of rows produced by successful Next calls.
	Rows uint64
	// DbHits is the number of logical storage accesses (see [DbHitsCounter]).
	DbHits uint64
	// ElapsedNs is the total nanoseconds spent inside Next across all calls.
	ElapsedNs int64
}

OperatorStats accumulates execution statistics for one operator.

type ProfileReport

type ProfileReport struct {
	// Operators holds per-operator statistics in the order they were added.
	Operators []OperatorStats
	// TotalRows is the sum of all operator row counts.
	TotalRows uint64
	// TotalDbHits is the sum of all operator dbHits.
	TotalDbHits uint64
	// ElapsedMs is the total wall-clock time in milliseconds.
	ElapsedMs float64
}

ProfileReport is the textual PROFILE output collected after draining a pipeline instrumented with ProfiledOperator wrappers.

type ProfiledOperator

type ProfiledOperator struct {
	// contains filtered or unexported fields
}

ProfiledOperator wraps an exec.Operator and records per-call statistics. It implements exec.Operator.

ProfiledOperator is NOT safe for concurrent use.

func NewProfiledOperator

func NewProfiledOperator(op exec.Operator, name string) *ProfiledOperator

NewProfiledOperator wraps op, assigning it the display name given by name.

func (*ProfiledOperator) Close

func (p *ProfiledOperator) Close() error

Close implements exec.Operator. It delegates to the inner operator.

func (*ProfiledOperator) Init

func (p *ProfiledOperator) Init(ctx context.Context) error

Init implements exec.Operator. It delegates to the inner operator.

func (*ProfiledOperator) Next

func (p *ProfiledOperator) Next(out *exec.Row) (bool, error)

Next implements exec.Operator. It delegates to the inner operator, incrementing Rows on each (true, nil) return and accumulating elapsed time.

func (*ProfiledOperator) Stats

func (p *ProfiledOperator) Stats() OperatorStats

Stats returns the accumulated statistics for this operator.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL