Skip to content

Commit ea4e642

Browse files
author
Dylan Storey
committed
chore: prepping for 0.2.0 release
1 parent 581a9dd commit ea4e642

File tree

13 files changed

+261
-25
lines changed

13 files changed

+261
-25
lines changed

.metis/backlog/bugs/GQLITE-T-0084.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0084.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ level: task
44
title: "Variable-length paths in MATCH+RETURN queries cause syntax error"
55
short_code: "GQLITE-T-0084"
66
created_at: 2026-01-04T15:19:14.677175+00:00
7-
updated_at: 2026-01-04T15:19:14.677175+00:00
7+
updated_at: 2026-01-05T15:30:11.166198+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
14-
- "#phase/backlog"
1514
- "#bug"
15+
- "#phase/completed"
1616

1717

1818
exit_criteria_met: false
@@ -52,6 +52,14 @@ Fix the parser/query dispatch to properly handle variable-length path patterns (
5252

5353
## Acceptance Criteria
5454

55+
## Acceptance Criteria
56+
57+
## Acceptance Criteria
58+
59+
## Acceptance Criteria
60+
61+
## Acceptance Criteria
62+
5563
- [ ] `MATCH path = (a)-[:REL*]->(b) RETURN b` executes without syntax error
5664
- [ ] Variable-length path with bounds works: `[:REL*1..3]`
5765
- [ ] CLI test added to verify this functionality
@@ -119,4 +127,13 @@ Low risk - this is additive functionality
119127

120128
## Status Updates **[REQUIRED]**
121129

122-
*To be added during implementation*
130+
### 2026-01-05: Completed
131+
- Root cause: `end` was a reserved keyword (for CASE...END) and couldn't be used as identifier
132+
- Fixed by adding `END_P` token to grammar rules for identifiers and property access
133+
- Updated `%expect-rr` from 2 to 3 to handle new GLR parser ambiguity
134+
- Added regression test `test_end_as_identifier_regression`
135+
- All 762 C unit tests pass
136+
- Committed as 3e2dc6e
137+
138+
Note: The original ticket title mentions "variable-length paths" but that feature works fine.
139+
The actual issue was using `end` as the variable name in the example query.

.metis/backlog/bugs/GQLITE-T-0085.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0085.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ level: task
44
title: "Simple CASE syntax not supported (CASE expr WHEN)"
55
short_code: "GQLITE-T-0085"
66
created_at: 2026-01-05T01:19:28.046936+00:00
7-
updated_at: 2026-01-05T01:19:28.046936+00:00
7+
updated_at: 2026-01-05T15:07:37.560421+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
14-
- "#phase/backlog"
1514
- "#bug"
15+
- "#phase/completed"
1616

1717

1818
exit_criteria_met: false
@@ -65,6 +65,14 @@ Support simple CASE syntax (`CASE expr WHEN value THEN result END`) in addition
6565
- **Benefits of Fixing**: {What improves after refactoring}
6666
- **Risk Assessment**: {Risks of not addressing this}
6767

68+
## Acceptance Criteria
69+
70+
## Acceptance Criteria
71+
72+
## Acceptance Criteria
73+
74+
## Acceptance Criteria
75+
6876
## Acceptance Criteria **[REQUIRED]**
6977

7078
- [ ] {Specific, testable requirement 1}
@@ -134,4 +142,11 @@ None - parser change only
134142

135143
## Status Updates **[REQUIRED]**
136144

137-
*To be added during implementation*
145+
### 2026-01-05: Completed
146+
- Added `operand` field to `cypher_case_expr` AST node in `cypher_ast.h`
147+
- Updated `make_case_expr` function to accept operand parameter
148+
- Added grammar rules in `cypher_gram.y` for simple CASE syntax
149+
- Updated transformer in `transform_return.c` to generate `operand = when_value` comparisons
150+
- Added regression test `test_simple_case_syntax_regression`
151+
- All 760 C unit tests pass
152+
- Committed as 893e7af

.metis/backlog/bugs/GQLITE-T-0086.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0086.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ level: task
44
title: "List function results lose column aliases in RETURN"
55
short_code: "GQLITE-T-0086"
66
created_at: 2026-01-05T01:19:28.139813+00:00
7-
updated_at: 2026-01-05T01:19:28.139813+00:00
7+
updated_at: 2026-01-05T14:53:19.002168+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
14-
- "#phase/backlog"
1514
- "#bug"
15+
- "#phase/completed"
1616

1717

1818
exit_criteria_met: false
@@ -65,6 +65,14 @@ Fix list-returning functions (range, tail, split) to preserve column aliases in
6565
- **Benefits of Fixing**: {What improves after refactoring}
6666
- **Risk Assessment**: {Risks of not addressing this}
6767

68+
## Acceptance Criteria
69+
70+
## Acceptance Criteria
71+
72+
## Acceptance Criteria
73+
74+
## Acceptance Criteria
75+
6876
## Acceptance Criteria **[REQUIRED]**
6977

7078
- [ ] {Specific, testable requirement 1}
@@ -134,4 +142,18 @@ None
134142

135143
## Status Updates **[REQUIRED]**
136144

137-
*To be added during implementation*
145+
### 2026-01-05: Fixed
146+
147+
**Root Cause**: `src/extension.c` had a special case (lines 221-225) that returned single-cell JSON arrays directly without the column name wrapper:
148+
```c
149+
if (result->row_count == 1 && result->column_count == 1 &&
150+
result->data[0][0] && result->data[0][0][0] == '[') {
151+
sqlite3_result_text(context, result->data[0][0], -1, SQLITE_TRANSIENT);
152+
}
153+
```
154+
155+
**Fix**: Removed this special case so all results go through the standard formatting path that includes column names.
156+
157+
**Commit**: `422284f` - "Fix list function results losing column aliases in RETURN"
158+
159+
**Regression Test**: Added `test_list_function_alias_regression` in `tests/test_executor_functions.c`

.metis/backlog/bugs/GQLITE-T-0087.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0087.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ level: task
44
title: "UNWIND does not support function calls like range()"
55
short_code: "GQLITE-T-0087"
66
created_at: 2026-01-05T01:19:28.236966+00:00
7-
updated_at: 2026-01-05T01:19:28.236966+00:00
7+
updated_at: 2026-01-05T14:54:06.739729+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
14-
- "#phase/backlog"
1514
- "#bug"
15+
- "#phase/completed"
1616

1717

1818
exit_criteria_met: false
@@ -65,6 +65,14 @@ Enable UNWIND to accept function calls that return lists (e.g., `UNWIND range(1,
6565
- **Benefits of Fixing**: {What improves after refactoring}
6666
- **Risk Assessment**: {Risks of not addressing this}
6767

68+
## Acceptance Criteria
69+
70+
## Acceptance Criteria
71+
72+
## Acceptance Criteria
73+
74+
## Acceptance Criteria
75+
6876
## Acceptance Criteria **[REQUIRED]**
6977

7078
- [ ] {Specific, testable requirement 1}

.metis/backlog/bugs/GQLITE-T-0088.md renamed to .metis/archived/backlog/bugs/GQLITE-T-0088.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ level: task
44
title: "WITH clause property access returns node ID instead of value"
55
short_code: "GQLITE-T-0088"
66
created_at: 2026-01-05T01:19:28.339318+00:00
7-
updated_at: 2026-01-05T01:19:28.339318+00:00
7+
updated_at: 2026-01-05T14:00:51.395200+00:00
88
parent:
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#task"
14-
- "#phase/backlog"
1514
- "#bug"
15+
- "#phase/completed"
1616

1717

1818
exit_criteria_met: false
@@ -65,6 +65,14 @@ Fix WITH clause to properly handle node variable projection so that subsequent p
6565
- **Benefits of Fixing**: {What improves after refactoring}
6666
- **Risk Assessment**: {Risks of not addressing this}
6767

68+
## Acceptance Criteria
69+
70+
## Acceptance Criteria
71+
72+
## Acceptance Criteria
73+
74+
## Acceptance Criteria
75+
6876
## Acceptance Criteria **[REQUIRED]**
6977

7078
- [ ] {Specific, testable requirement 1}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
id: keys-function-sql-generation-uses
3+
level: task
4+
title: "keys() function SQL generation uses broken EXISTS with UNION ALL"
5+
short_code: "GQLITE-T-0089"
6+
created_at: 2026-01-05T14:30:55.659606+00:00
7+
updated_at: 2026-01-05T15:15:21.710597+00:00
8+
parent:
9+
blocked_by: []
10+
archived: true
11+
12+
tags:
13+
- "#task"
14+
- "#bug"
15+
- "#phase/completed"
16+
17+
18+
exit_criteria_met: false
19+
strategy_id: NULL
20+
initiative_id: NULL
21+
---
22+
23+
# keys() function SQL generation uses broken EXISTS with UNION ALL
24+
25+
*This template includes sections for various types of tasks. Delete sections that don't apply to your specific use case.*
26+
27+
## Parent Initiative **[CONDITIONAL: Assigned Task]**
28+
29+
[[Parent Initiative]]
30+
31+
## Objective
32+
33+
Fix the `keys()` function to return the correct list of property keys for a node.
34+
35+
## Backlog Item Details
36+
37+
### Type
38+
- [x] Bug - Production issue that needs fixing
39+
40+
### Priority
41+
- [ ] P2 - Medium (nice to have)
42+
43+
### Impact Assessment
44+
- **Affected Users**: Any user calling keys(n) on a node
45+
- **Reproduction Steps**:
46+
1. `CREATE (n:Person {name: "Alice", age: 30})`
47+
2. `MATCH (n:Person) RETURN keys(n)`
48+
3. Returns `[]` instead of `["name", "age"]`
49+
- **Expected vs Actual**:
50+
- Expected: `["name", "age"]`
51+
- Actual: `[]` (empty array)
52+
53+
### Root Cause
54+
55+
The generated SQL uses `EXISTS (SELECT 1 ... UNION ALL SELECT 1 ...)` pattern which doesn't work correctly in SQLite:
56+
57+
```sql
58+
-- BROKEN (current implementation):
59+
EXISTS (SELECT 1 FROM node_props_text WHERE node_id = n.id AND key_id = pk.id
60+
UNION ALL
61+
SELECT 1 FROM node_props_int WHERE node_id = n.id AND key_id = pk.id)
62+
63+
-- WORKING (should be):
64+
EXISTS (SELECT 1 FROM node_props_text WHERE node_id = n.id AND key_id = pk.id)
65+
OR EXISTS (SELECT 1 FROM node_props_int WHERE node_id = n.id AND key_id = pk.id)
66+
```
67+
68+
### File Location
69+
- `src/backend/transform/transform_func_entity.c` - `transform_keys_function()`
70+
71+
## Acceptance Criteria
72+
73+
## Acceptance Criteria
74+
75+
## Acceptance Criteria
76+
77+
## Acceptance Criteria
78+
79+
## Acceptance Criteria
80+
81+
- [ ] `MATCH (n:Person) RETURN keys(n)` returns correct property keys
82+
- [ ] `MATCH (n) UNWIND keys(n) AS key RETURN key` works correctly
83+
- [ ] Regression test added for keys() function
84+
85+
## Test Cases **[CONDITIONAL: Testing Task]**
86+
87+
{Delete unless this is a testing task}
88+
89+
### Test Case 1: {Test Case Name}
90+
- **Test ID**: TC-001
91+
- **Preconditions**: {What must be true before testing}
92+
- **Steps**:
93+
1. {Step 1}
94+
2. {Step 2}
95+
3. {Step 3}
96+
- **Expected Results**: {What should happen}
97+
- **Actual Results**: {To be filled during execution}
98+
- **Status**: {Pass/Fail/Blocked}
99+
100+
### Test Case 2: {Test Case Name}
101+
- **Test ID**: TC-002
102+
- **Preconditions**: {What must be true before testing}
103+
- **Steps**:
104+
1. {Step 1}
105+
2. {Step 2}
106+
- **Expected Results**: {What should happen}
107+
- **Actual Results**: {To be filled during execution}
108+
- **Status**: {Pass/Fail/Blocked}
109+
110+
## Documentation Sections **[CONDITIONAL: Documentation Task]**
111+
112+
{Delete unless this is a documentation task}
113+
114+
### User Guide Content
115+
- **Feature Description**: {What this feature does and why it's useful}
116+
- **Prerequisites**: {What users need before using this feature}
117+
- **Step-by-Step Instructions**:
118+
1. {Step 1 with screenshots/examples}
119+
2. {Step 2 with screenshots/examples}
120+
3. {Step 3 with screenshots/examples}
121+
122+
### Troubleshooting Guide
123+
- **Common Issue 1**: {Problem description and solution}
124+
- **Common Issue 2**: {Problem description and solution}
125+
- **Error Messages**: {List of error messages and what they mean}
126+
127+
### API Documentation **[CONDITIONAL: API Documentation]**
128+
- **Endpoint**: {API endpoint description}
129+
- **Parameters**: {Required and optional parameters}
130+
- **Example Request**: {Code example}
131+
- **Example Response**: {Expected response format}
132+
133+
## Implementation Notes **[CONDITIONAL: Technical Task]**
134+
135+
{Keep for technical tasks, delete for non-technical. Technical details, approach, or important considerations}
136+
137+
### Technical Approach
138+
{How this will be implemented}
139+
140+
### Dependencies
141+
{Other tasks or systems this depends on}
142+
143+
### Risk Considerations
144+
{Technical risks and mitigation strategies}
145+
146+
## Status Updates **[REQUIRED]**
147+
148+
### 2026-01-05: Completed
149+
- Fixed SQL generation in `transform_func_entity.c` for both `keys()` and `properties()` functions
150+
- Changed `EXISTS (... UNION ALL ...)` pattern to use separate `EXISTS ... OR EXISTS ...` checks
151+
- SQLite doesn't handle EXISTS with UNION ALL correctly
152+
- Added regression test `test_keys_function_regression`
153+
- All 761 C unit tests pass
154+
- Committed as 977d5e1

.metis/strategies/NULL/initiatives/GQLITE-I-0022/initiative.md renamed to .metis/archived/strategies/NULL/initiatives/GQLITE-I-0022/initiative.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ created_at: 2025-12-25T20:16:11.339561+00:00
77
updated_at: 2026-01-04T14:34:29.624102+00:00
88
parent: GQLITE-V-0001
99
blocked_by: []
10-
archived: false
10+
archived: true
1111

1212
tags:
1313
- "#initiative"

0 commit comments

Comments
 (0)