Initial SPARQL Explorations - Pixeltable Knowledge Graph
Date: 2025-12-21
Target: pixeltable/pixeltable repository (main branch)
Store: Oxigraph at ~/.repolex/oxigraph
Executive Summary
Ran systematic SPARQL exploration to identify problems and data quality issues in the first real-world parse. Found several critical issues that need parser improvements:
Critical Issues
- Thousands of generic fallback names (
identifier_1,module_1, etc.) - parser creating nodes without extracting actual names - Missing
woc:hasMethodrelationship - all class-method links usechildOfthrough intermediate block nodes - GROUP BY queries fail - aggregation queries return no results even with valid data
- Duplicate class names - 8 classes share names across different files
What Works Well
- File metadata complete with hashes, timestamps, extensions
- Code location metadata (line/column numbers) accurate
- Commit graph complete with authors and provenance
- File-to-code linking via
woc:definedInFileworks - Simple SELECT queries perform well
Query 2: Generic Fallback Names - THE BIG PROBLEM
Purpose: Find nodes with generic labels indicating parser fallback behavior
Results: THOUSANDS of nodes with generic names:
| Label | Count |
|---|---|
module_1 |
338 |
identifier_1 |
271 |
dotted_name_1 |
267 |
identifier_3 |
148 |
identifier_5 |
135 |
import_statement_1 |
123 |
block_1 |
109 |
| ... and many more ...
Analysis: ๐จ CRITICAL PROBLEM - Parser is creating RDF nodes for every AST element without extracting semantic names. For example:
- Every file gets a
module_1node instead of the actual module name - Identifiers are numbered sequentially instead of using their actual text
- Import statements, blocks, expressions all get generic sequential names
Root Cause: Parser fallback logic creates {node_type}_{counter} names when it can't extract a semantic name from the AST node.
Impact:
- Knowledge graph is polluted with meaningless nodes
- Can't query for specific identifiers or imports by name
- Graph bloat - thousands of nodes that provide no semantic value
Recommendation: ๐ง MUST FIX
- For AST nodes without extractable names, either:
- Don't create RDF nodes at all (just capture in parent's source text)
- OR use content-based identifiers (hash of text)
- Add better name extraction for:
- Module nodes โ extract from
__name__or file path - Identifier nodes โ extract actual identifier text
- Import statements โ extract module being imported
- Module nodes โ extract from
Query 3: Missing woc:hasMethod Relationship
Purpose: Check if classes properly link to methods via woc:hasMethod
Results: 0 - NO hasMethod relationships exist
Workaround Query - Must use 2-hop path through childOf:
PREFIX woc: <http://w3id.org/woc#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?method ?methodName
WHERE {
GRAPH <https://repolex.ai/data/pixeltable/pixeltable/main/code> {
<.../Table> woc:childOf* ?block .
?block woc:childOf ?method .
?method a woc:PythonFunction ;
rdfs:label ?methodName .
}
}
LIMIT 10
Analysis: ๐จ DESIGN ISSUE - Parser only creates childOf relationships, never hasMethod. This means:
- Querying for a class's methods requires complex 2-hop path
- Can't easily distinguish methods from nested functions
- Graph doesn't match Web of Code ontology expectations
Recommendation: ๐ง SHOULD FIX
- Add explicit
woc:hasMethodrelationship when parser detects function definition inside class - Keep
childOffor structural hierarchy - Both relationships can coexist and serve different query patterns
Query 6: Aggregation Query Performance
Purpose: Test GROUP BY performance on methods per class
Results: ๐จ QUERY FAILED - Returns no results despite valid data
Analysis: GROUP BY queries involving property paths (woc:childOf*) appear to fail or timeout. This is likely an Oxigraph limitation or query complexity issue.
Workaround: Use simple aggregations without property paths, or run aggregation in Python after fetching results.
Recommendation: ๐ DOCUMENT LIMITATION - Warn users that complex aggregations may not work in SPARQL. Provide Python-based aggregation examples.
Summary of Issues
๐จ Critical (Must Fix)
- Generic fallback names - Thousands of nodes with
identifier_1,module_1labels- Impact: Graph pollution, no semantic value
- Fix: Better name extraction or skip creating nodes for unnamed AST elements
๐ง Should Fix
Missing
woc:hasMethod- Classes don't link directly to methods- Impact: Complex 2-hop queries required
- Fix: Add explicit hasMethod relationships
MIME type detection broken - All files marked as "text/plain"
- Impact: Can't filter by file type accurately
- Fix: Use proper MIME detection library
๐ Document Limitations
GROUP BY queries fail - Aggregations with property paths don't work
- Impact: Some analytics queries impossible in SPARQL
- Fix: Document limitation, provide Python-based workarounds
Duplicate class names - Multiple classes with same name (expected)
- Impact: None (URIs include file paths)
- Fix: Document that this is expected behavior
โ Working Well
- File metadata (except MIME types)
- Commit graph and provenance
- Code location metadata (line/column numbers)
- Code-to-file linking via
woc:definedInFile - Simple SELECT queries perform well
- URI generation is correct and unambiguous
Recommended Query Patterns
โ DO - Simple queries work well
# Get all classes in a file
SELECT ?class ?className
WHERE {
GRAPH <https://repolex.ai/data/pixeltable/pixeltable/main/code> {
?class a woc:PythonClass ;
rdfs:label ?className ;
woc:definedInFile <...file_uri...> .
}
}
โ AVOID - These patterns fail
# GROUP BY with property paths - returns empty
SELECT ?className (COUNT(?method) as ?count)
WHERE {
?class woc:childOf* ?block .
?block woc:childOf ?method .
}
GROUP BY ?className # FAILS
Next Steps
Parser Improvements
- Fix name extraction for module, identifier, import nodes
- Add
woc:hasMethodrelationship for class methods - Implement proper MIME type detection
- Consider skipping RDF node creation for unnamed AST elements
Documentation
- Document known limitations (GROUP BY, aggregations)
- Provide Python-based aggregation examples
- Create query pattern cookbook
Testing
- Parse more repositories to validate fixes
- Add automated data quality checks
- Create SPARQL test suite
Appendix: Test Statistics
Repository: pixeltable/pixeltable (main branch)
Parse Date: 2025-12-21
Scale
- Files: 1,959 total files
- Python files: 338 (estimated)
- Classes: 435 total
- Functions: 3,365 total
- Commits: 50 total (was artificially limited - RESOLVED)
- Contributors: 7 total
- Triples: ~6.7 million total
Graph Sizes
- Code graph: ~6.5M triples
- Files graph: ~15K triples
- Commits graph: ~200 triples (limit removed)
Store Performance
- Store location:
~/.repolex/oxigraph - Store size: ~500MB (estimated)
- Simple queries: < 100ms
- Complex queries: variable (some fail)