Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
83 changes: 83 additions & 0 deletions CALCULATED_FIELDS_FIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Fix for Calculated Fields Not Showing in Copy Board Query Analysis

## Problem
When analyzing boards in the copy-board feature, the list of columns in the query did not include calculated fields (derived columns). This was because:

1. The `ColumnInfo` type definition was incomplete and didn't include fields specific to derived columns
2. The column filtering logic only checked `key_name`, but derived columns are referenced by their `alias` in queries

## Solution

### Changes Made to `src/copy-board/analyzeBoard.ts`

#### 1. Updated `ColumnInfo` Type Definition (lines 34-42)
Added fields that are present in derived column responses from the Honeycomb API:
```typescript
type ColumnInfo = {
key_name: string;
type: string;
description?: string;
hidden?: boolean;
id?: string; // Added for derived columns
alias?: string; // Added for derived columns
expression?: string; // Added for derived columns
};
```

#### 2. Updated Column Filtering Logic (lines 153-161)
Modified the filter to check both `key_name` (for regular columns) and `alias` (for derived columns):
```typescript
if (!isFetchError(columnsResponse)) {
// Extract column names used in the query
const usedColumns = extractColumnsFromQuery(queryDef);
// Filter to only show columns used in the query
// For derived columns, check both key_name and alias
columns = columnsResponse.filter((col) =>
usedColumns.has(col.key_name) || (col.alias && usedColumns.has(col.alias))
);
}
```

#### 3. Enhanced Column Display (lines 249-264)
Updated the `renderColumns` function to:
- Display the `alias` for derived columns (instead of `key_name`)
- Indicate when a column is derived by showing "derived" in the type information
```typescript
function renderColumns(columns: ColumnInfo[]): Html {
if (!columns || columns.length === 0) {
return html``;
}
return html`<div class="query-section">
<strong>Columns Used (${columns.length}):</strong>
<ul>
${columns.map((col) => {
const displayName = col.alias || col.key_name;
const isDerived = col.alias && col.expression;
const typeInfo = isDerived ? `derived (${col.type})` : col.type;
return html`<li><code>${displayName}</code>: ${typeInfo}</li>`;
})}
</ul>
</div>`;
}
```

## How It Works

1. When the Honeycomb API returns columns from the `/columns/{dataset}` endpoint, it includes both regular columns and derived columns
2. Regular columns have a `key_name` field
3. Derived columns have both a `key_name` and an `alias` field (plus an `expression` field containing the formula)
4. In queries, derived columns are referenced by their `alias`, not their `key_name`
5. The fix ensures that when matching columns used in a query, we check both `key_name` and `alias`
6. The display now shows the `alias` for derived columns and marks them as "derived" for clarity

## Testing

To verify the fix:
1. Create a board with queries that use derived columns (calculated fields)
2. Use the copy-board feature to analyze the board
3. Verify that derived columns now appear in the "Columns Used" section
4. Verify that they are marked as "derived" in the type information

## Impact

This fix ensures that all columns used in a query, including calculated fields, are properly displayed when analyzing boards. This is important for understanding query dependencies and for the copy-board functionality to work correctly.
98 changes: 98 additions & 0 deletions CHANGES_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Summary of Changes

## 1. Board List Links (Previous Change)

### Overview
Made each board in the board list clickable, linking directly to the board's URL in Honeycomb.

### Files Modified
- `src/copy-board/listBoards.ts` - Added board link construction
- `public/styles.css` - Added styles for board links

---

## 2. Fix for Calculated Fields in Copy Board (Current Change)

### Issue
When using the copy-board feature to analyze boards, the list of columns in queries did not include calculated fields (derived columns). This made it difficult to understand the full dependencies of queries that used calculated fields.

### Root Cause
The issue had two parts:
1. **Incomplete type definition**: The `ColumnInfo` type didn't include fields specific to derived columns (`id`, `alias`, `expression`)
2. **Incorrect filtering logic**: The column filtering only checked `key_name`, but derived columns are referenced by their `alias` in queries, not their `key_name`

### Changes Made

#### File: `src/copy-board/analyzeBoard.ts`

**1. Enhanced `ColumnInfo` Type (lines 34-42)**
```typescript
type ColumnInfo = {
key_name: string;
type: string;
description?: string;
hidden?: boolean;
id?: string; // NEW: Unique identifier for derived columns
alias?: string; // NEW: The name used to reference derived columns in queries
expression?: string; // NEW: The formula/expression for derived columns
};
```

**2. Fixed Column Filtering Logic (lines 153-161)**
```typescript
// Filter to only show columns used in the query
// For derived columns, check both key_name and alias
columns = columnsResponse.filter((col) =>
usedColumns.has(col.key_name) || (col.alias && usedColumns.has(col.alias))
);
```

**3. Improved Column Display (lines 249-264)**
Now derived columns:
- Display their `alias` (the name used in queries) instead of their internal `key_name`
- Are marked as "derived" in the type information for clarity

### Testing
Created comprehensive unit tests in `test/analyzeBoard.test.ts` that verify:
- Regular columns are matched by `key_name` ✅
- Derived columns are matched by `alias` ✅
- Both regular and derived columns can be matched together ✅
- Derived columns are correctly identified and displayed ✅

All tests pass successfully.

### Impact

**Before the Fix:**
- Queries using calculated fields would show incomplete column lists
- Users couldn't see which calculated fields were being used

**After the Fix:**
- All columns, including calculated fields, are now displayed
- Calculated fields are clearly marked as "derived"
- Complete visibility into query dependencies

### Example Output

**Before:**
```
Columns Used (2):
- duration: float
- status_code: integer
```

**After:**
```
Columns Used (3):
- duration: float
- status_code: integer
- error_rate: derived (float)
```

### Files Modified
- `src/copy-board/analyzeBoard.ts` - Main implementation
- `src/copy-board/analyzeBoard.js` - Compiled JavaScript (auto-generated)

### Files Added
- `test/analyzeBoard.test.ts` - Unit tests for the fix
- `CALCULATED_FIELDS_FIX.md` - Detailed technical documentation
88 changes: 88 additions & 0 deletions COLUMN_DISPLAY_CHANGES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Copy-Board Page: Column Display Enhancement

## Summary
Modified the copy-board page to display only the columns involved in each query, along with their types.

## Changes Made

### File: `src/copy-board/analyzeBoard.ts`

#### 1. Added ColumnInfo Type
```typescript
type ColumnInfo = {
key_name: string;
type: string;
description?: string;
hidden?: boolean;
};
```

#### 2. Added extractColumnsFromQuery Function
This function extracts all column names used in a query by examining:
- **Calculations**: Columns used in aggregation operations (e.g., `COUNT(column)`)
- **Filters**: Columns used in WHERE clauses
- **Breakdowns**: Columns used for GROUP BY operations
- **Orders**: Columns used in ORDER BY clauses
- **Havings**: Columns used in HAVING clauses

#### 3. Enhanced analyzeBoard Function
- Now fetches column information from the Honeycomb API using the endpoint: `columns/{dataset}`
- Filters the column list to show only columns that are actually used in the query
- Passes the filtered column list to the rendering functions

#### 4. Added renderColumns Function
Displays the columns used in a query with the following format:
```
Columns Used (N):
- column_name: column_type
- another_column: another_type
```

The columns are displayed in a `<code>` tag for better readability.

#### 5. Updated Type Signatures
Updated the type signatures for:
- `renderPanels()` - Now includes `columns: ColumnInfo[]` in the item type
- `renderQueryPanel()` - Now includes `columns: ColumnInfo[]` in the item type

## How It Works

1. When a board is analyzed, the system fetches the board details and all query definitions
2. For each query, it:
- Extracts all column names used in the query
- Fetches all columns from the dataset via the Honeycomb API
- Filters to show only the columns that appear in the query
3. The filtered column list is displayed at the top of each query's details section, showing:
- The column name (in monospace font)
- The column type
- A count of how many columns are used

## Display Order

The query details now display in this order:
1. **Query ID**
2. **Dataset**
3. **Columns Used** (NEW - shows only columns involved in the query with their types)
4. Calculations
5. Breakdowns
6. Filters
7. Order
8. Having
9. Time range
10. Limit

## Benefits

- **Clarity**: Users can immediately see which columns are involved in a query
- **Type Information**: Column types are displayed, helping users understand data types
- **Efficiency**: Only relevant columns are shown, not the entire dataset schema
- **Debugging**: Makes it easier to identify missing or incorrect column references

## API Endpoint Used

The implementation uses the Honeycomb API endpoint:
```
GET /columns/{dataset}
```

This returns an array of column information including `key_name`, `type`, and other metadata.
74 changes: 74 additions & 0 deletions EXAMPLE_OUTPUT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Example Output: Copy-Board Page with Column Display

## Before the Change

When viewing a query on the copy-board page, you would see:

```
Query 1 (my-dataset)
Query ID: abc123
Dataset: my-dataset

Calculations:
- COUNT()
- AVG(duration_ms)

Breakdowns: service.name, http.status_code

Filters:
- error = true
- duration_ms > 1000

Order:
- COUNT() desc
```

## After the Change

Now you will see the columns involved in the query listed first with their types:

```
Query 1 (my-dataset)
Query ID: abc123
Dataset: my-dataset

Columns Used (3):
- duration_ms: float
- service.name: string
- http.status_code: integer
- error: boolean

Calculations:
- COUNT()
- AVG(duration_ms)

Breakdowns: service.name, http.status_code

Filters:
- error = true
- duration_ms > 1000

Order:
- COUNT() desc
```

## Key Benefits

1. **Immediate Visibility**: You can see at a glance which columns are used in the query
2. **Type Information**: Each column's type is displayed (string, integer, float, boolean, etc.)
3. **Filtered List**: Only columns actually used in the query are shown, not the entire dataset schema
4. **Better Planning**: When copying a board to another environment, you can verify that all required columns exist in the target dataset

## Technical Details

The column information is fetched from the Honeycomb API endpoint:
```
GET /columns/{dataset}
```

The system then filters this list to show only columns that appear in:
- Calculations (e.g., `AVG(duration_ms)`)
- Filters (e.g., `error = true`)
- Breakdowns (e.g., `service.name`)
- Order clauses (e.g., `duration_ms desc`)
- Having clauses (e.g., `COUNT() > 100`)
Loading