Feature/plsql support#1033
Open
ouzsrcm wants to merge 51 commits into
Open
Conversation
Vendors AndreasMaierDe/tree-sitter-plsql @ 28aebef (MIT, ABI 14, no external scanner) and adds the grammar_plsql.c compile shim. Updates MANIFEST.md and THIRD_PARTY.md grammar counts. Local patch: quoted tree_sitter/parser.h include so the per-grammar header resolves. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
Register Oracle PL/SQL in lang_specs (packages/types/triggers as Class, procedures/functions as Function, ref_call/branches/assign/raise) and map .pks/.pkb/.pck/.pls/.plb/.plsql/.fnc/.trg/.bdy/.tps/.tpb. Leave .sql and .prc unchanged. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
Resolve fnc_name/prc_name for procedures and functions, package_name/ type_name/trigger_name for Class nodes, and package-qualified ref_call callees (PKG.FNC) for CALLS edges. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
Add extension/extraction/grammar regression+label tests for PL/SQL, plus emp_pkg/util_pkg fixtures verifying Class/Function and CALLS. Document CREATE TYPE ... AS OBJECT as a known grammar ERROR-node limitation. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
Owner
|
Thanks for the PL/SQL contribution. I verified the vendored parser against AndreasMaierDe/tree-sitter-plsql at commit 28aebef209be: it is MIT licensed and byte-identical across 353,744 lines except for the documented local include-path change. This is a 0.9.2-rc language enhancement; remaining review focuses on full build and sanitizer coverage, grammar limits, extraction quality, and representative PL/SQL fixtures. |
Three of DeusData#797's four findings fixed (the fourth — repeated-variable unification — already holds on main and is now pinned by the test): - Walk padding: the BFS recursive CTE deduped (node, hop) PAIRS, so a single self-loop minted every hop level for every node it could reach — *k..k matched fabricated walks of arbitrary length (a 100-hop 'longest chain' artifact) and the row set exploded to nodes x depth (the reported crash). The traversal now returns each node once at its MINIMAL hop (MIN/GROUP BY): variable-length matches nodes whose shortest path lies in [min,max]. This is deliberately shortest-path semantics, not openCypher trail enumeration — right for reachability/depth audits on call graphs and linear instead of exponential; trace_path shares the traversal and now also reports each node once on cyclic graphs. - Silent 100-hop cap: a clamped hop range now surfaces as result->warning ('clamped ... an empty result may mean clamped, not no such path'), emitted by query_graph in both TOON and JSON forms, on top of the existing log WARN. Reproduce-first: cypher_exec_varlength_path_semantics_issue797 — self-loop + real 2-chain fixture; RED on the walk semantics (*2..2 returned 3 endpoints instead of 1), GREEN now, incl. variable unification, zero rows for nonexistent path lengths, and the clamp warning assertion. Closes DeusData#797 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The compat.h include added for CBM_TLS pulled windows.h into cypher.c, whose legacy 'far' macro (windef.h defines it empty) broke the existing EXISTS-pattern local of that name on every Windows leg. Use C11 _Thread_local for the depth-clamp flag instead; cypher.c stays free of windows.h. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…solution
const foo = require('./foo') emitted a Variable definition for the
binding, so calls to foo() resolved to that same-module Variable (an
import alias, not a definition) instead of following the recorded
import to the exported function - which stayed at zero inbound CALLS
and surfaced as a disconnected Variable node. ESM import bindings never
materialize as Variables; the identifier-bound require form now behaves
identically: extract_js_vars skips the Variable def exactly when the
declarator value is a require() call with a string-literal path (the
form extract_imports records with local_name = the identifier), letting
resolution fall through to the import map. Destructured requires keep
their Variable defs since the import row only records the module.
Closes DeusData#871
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
cbm_store_find_node_by_id heap-allocates the node's string fields; the DeusData#871 helper left them unfreed, tripping LSan on the Linux legs. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
A persistently dirty or untracked worktree re-triggered a full reindex (and its DB/artifact rewrite) on every poll cycle - git_is_dirty() answered 'is the tree dirty' where the watcher needs 'did the tree CHANGE'. Idle repos with one uncommitted file produced sustained disk write amplification (reported at 1 TB/day across several repos). The watcher now tracks a dirty-state signature: FNV-1a over the entries of git status --porcelain -uall -z plus each listed path's (size, mtime_ns). Same signature -> no reindex; editing a dirty file, adding/removing one, or reverting the tree to clean each produce a new signature and trigger exactly one reindex. Submodule status is folded in on POSIX, mirroring the old submodule dirty probe. 0 is reserved for a clean tree; a dirty-at-baseline tree still reindexes once (the watcher cannot know whether that state reached the DB, e.g. after a server restart with a stale artifact). Baselines (HEAD and signature) are now committed only after a SUCCESSFUL reindex: check_changes stages observations in pending_* fields, and busy-skips (index_fn > 0, e.g. pipeline lock held) or failed runs leave the baselines untouched so the change is retried on the next poll instead of being recorded as seen and silently lost - the old code stored the new HEAD at check time, dropping any commit that arrived while the pipeline was busy. Closes DeusData#937 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The DeusData#599 receiver-aware narrowing (87091ed) shipped without coverage for the delegation/store bucket reported in DeusData#876: same-named calls whose receiver is a call result (_get_store().get inside get), a module singleton (_default.check inside check), or a loop-local cursor (cur.execute inside execute). All three are clean on current main; this guard pins the bucket so it cannot regress. Refs DeusData#876 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…ions A function whose body braces are split across #ifdef/#else branches (one open brace per branch, a single shared close) parses with an ERROR region on the raw source - both branches are present at once, so the braces are unbalanced - and the defs walk silently dropped it while its callers stayed as unresolved names (cbm_path_within_root, handle_process_kill). The preprocessed second pass (simplecpp) already exists for macro- hidden CALLS; it evaluates the conditionals, so one branch is chosen and the expanded tree parses clean, with same-file token lines aligned to the original. Recover definitions from it, adopting only defs that (a) intersect a raw-tree ERROR region, (b) have their name visible on the corresponding original source line (rejects header-inlined defs whose physical expanded lines alias unrelated raw lines when compile_commands include paths resolve), and (c) are absent by qualified name from the raw pass. Verified on the real instances: handle_process_kill (580-647) and cbm_path_within_root (5070-5085) both index with correct line ranges. Closes DeusData#961 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
cbm_pipeline_fqn_compute strips the file extension, so a C/C++ header and its same-stem source collide on both the module QN and the File QN. Node upserts match by QN, so the header's File node is merged into the source's - the header has no node of its own and can never receive an inbound IMPORTS edge; the reporter's zero-inbound query flags 194 of 214 files. The module-QN unification is (at least partly) load-bearing for C/C++ declaration/definition call joins, and the File-node creation sites overlap PR DeusData#995's pending fix for DeusData#994, so the fix is deferred to land on top of that. This RED reproduction (non-gating repro tier) keeps the bug tracked until then. Refs DeusData#964 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…isses Agents naturally pass the repo folder name (codebase-memory-mcp), but indexed project names derive from the full path (E:\project\graph\x -> E-project-graph-x), so every graph tool answered 'project not found or not indexed' while list_projects clearly showed the project. get_project_arg now falls back to a cache-dir filename scan when no <project>.db exists: a passed name matching exactly ONE indexed project as a segment-aligned tail (-<name>.db) adopts that project's full name (logged); zero or several matches keep the original name so the existing not-found error with the candidate list fires. Exact names never enter the scan, and internal-name drift stays DeusData#704's fallback in resolve_store. Closes DeusData#1025 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Aider has no MCP support - it reads CONVENTIONS.md but can only run shell commands. The installer wrote the shared MCP-tool-centric instructions there, telling the model to call search_graph(...) etc., tools Aider cannot invoke; a reporter reasonably asked how that was ever supposed to work (DeusData#1032). Aider now gets a dedicated variant: the same discovery priority expressed as runnable codebase-memory-mcp cli commands (usable via /run), including first-index and list_projects bootstrapping, with the no-MCP constraint stated explicitly. Closes DeusData#1032 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…fire The 300ms in-process SIGALRM budget in hook-augment self-terminated with a silent _exit(0) on real cold starts (SQLite/mmap open under load), so PreToolUse augmentation never appeared in real sessions (reporter: 0/24 observed) while warm manual invocations worked - and a fired deadline was indistinguishable from a legitimate no-match run. Default budget is now 2000ms (the settings.json hook timeout stays the outer backstop), overridable via CBM_HOOK_DEADLINE_MS (clamped 50..10000). When the deadline fires, the handler write()s a pre-formatted breadcrumb (deadline, pid, the env knob to raise) to ~/.cache/codebase-memory-mcp/logs/hook-augment-timeouts.log before exiting - fd and message are prepared at arm time so the handler stays async-signal-safe; CBM_HOOK_TIMEOUT_LOG overrides the path for tests. Windows keeps relying on the settings.json timeout (unchanged no-op). Deterministic reproduction: stdin is a pipe whose writer never sends, so the read blocks past a 60ms deadline - the timer must fire, exit 0 (fail-open), and leave the breadcrumb. RED before (no breadcrumb), GREEN after. Closes DeusData#858 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
ha_deadline_ms was defined unconditionally but only used by the POSIX ha_arm_deadline - unused-function under -Werror broke every Windows leg. The knob, its constants and the doc comment now live inside the same #ifndef _WIN32 block as the deadline machinery they configure; Windows continues to rely solely on the settings.json hook timeout. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Extensionless bash shims under %USERPROFILE%\.claude\hooks triggered the Windows 'How do you want to open this file?' dialog whenever an editor (Cursor) scanned the hooks dir, and could not execute without bash anyway. All three Claude hook scripts (discovery gate, session reminder, subagent reminder) now install as .cmd files with cmd syntax on Windows - @echo off bodies, caret-escaped pipes in the reminder text, 2>/dev/null redirects - and the install removes the pre-existing extensionless twin so upgrades stop triggering the dialog. The settings.json command paths follow automatically since they are built from the same script-name macros. POSIX behavior is byte-identical and guarded (no .cmd twin). Closes DeusData#929 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The 8e gate compared uname -s to the bare literal MINGW64_NT, which never matches the real value (MINGW64_NT-10.0-...), so the POSIX branch silently ran on Windows and looked for the extensionless shim that DeusData#929 no longer installs. Branch by platform prefix: Windows expects the .cmd shim and the absence of the legacy extensionless twin; POSIX unchanged. Content checks (never blocks, delegates to hook-augment) now run on both. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
cbm_writer_open used a raw ANSI-CP fopen for the hand-rolled SQLite writer - the one file-creating call on the dump chain without a UTF-8-to-wide conversion. On a non-ASCII Windows profile (C:\Users\Kovacs Janos) extract and resolve succeeded but the dump failed with pipeline.err phase=dump: fopen could not create graph.db under the profile-derived cache dir while cbm_mkdir_p (already wide) had happily created the directory around it. Routed through cbm_fopen, matching DeusData#700 (pass readers) and DeusData#973 (canonicalization); POSIX is byte-transparent. New Windows guard test_non_ascii_cache_dump.py indexes an ASCII repo into a non-ASCII CBM_CACHE_DIR and requires a query_graph readback with Function count > 0 - proving the DB was written to and reopened from the non-ASCII cache, not merely that no error surfaced. The existing non-ASCII guard only varied the repo path against an ASCII cache, which is why this class went unseen. The USERPROFILE-sourced env encoding question (Layer 2 - _environ is ANSI-CP, not UTF-8) is deliberately not bundled; it needs verification on a real Windows box and will be filed separately if the guard alone does not settle it. Closes DeusData#996 Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Layer 2 of DeusData#996, forced by the new guard going RED on the Windows CI leg with the writer fix alone: _environ holds ANSI-code-page bytes, not UTF-8, so a non-ASCII USERPROFILE or CBM_CACHE_DIR arrives either mojibake'd or with unrepresentable characters replaced by '?' - which is invalid in Windows paths, so every downstream wide-safe file API fails no matter how correct it is. cbm_safe_getenv now reads the value via GetEnvironmentVariableW and converts to genuine UTF-8 (cbm_wide_to_utf8), matching the UTF-8-path convention the rest of the codebase assumes; missing variables honor the fallback as before, and conversion trouble falls back to the ANSI scan rather than failing. POSIX untouched. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Real Laravel apps register routes through the Illuminate facade, whose
class lives in vendor/ and is never indexed - and for that style the
graph minted ZERO Route nodes, flat or grouped. Three stacked defects:
1. The callee of Route::get(...) (scoped_call_expression) was
extracted as bare 'get' via generic field resolution, so the
empty-resolution route fallback ('::get' suffix table) could never
engage. The extractor now emits the qualified 'Route::get' form,
gated to the literal Route scope AND a route-method table match so
Cache::get / Config::get keep bare names and can never mint junk
(guarded by an inverse test; the path gate additionally requires a
leading '/').
2. The sequential pass had no ROUTE_REG empty-resolution fallback at
all (its comment claimed parity with the parallel path, which has
one) - unresolvable route registrations were dropped entirely.
Added, mirroring the parallel callee_suffix fallback.
3. Nothing composed enclosing prefix()->group() chains (same class as
Spring's DeusData#734). At extraction - the only place the AST still exists
- each route call inside group closures now walks its ancestors:
every enclosing closure that is the argument of ->group(...)
contributes the prefix('...') found on that group call's receiver
chain, outer-to-inner for nested groups; middleware/name/domain
chain links are skipped.
The existing handles_laravel_php test kept passing throughout because
its fixture defines an in-tree Route class, resolving by QN - which is
exactly how this class stayed unseen.
Closes DeusData#952
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The previous commit's clang-format -i rewrote all of test_edge_types_probe.c (+732/-358 for a 48-line test addition) - my local formatter's whole-file drift, not real non-conformance (lint-ci passes on the restored file). Restore the file to main's formatting with only the two DeusData#952 tests added. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Add ObjectScript (InterSystems IRIS / Caché) as a supported language,
covering the UDL class format (.cls), MAC/INT routines (.mac/.int/.rtn),
include/macro files (.inc), and IRIS Studio Export XML.
Definition extraction (extract_defs.c): Class, Method, ClassMethod,
Property, Parameter, Index, Trigger (with body text), XData, Storage,
and Query members as graph nodes; base classes from the Extends clause.
Call dispatch resolution (extract_calls.c) — four ObjectScript patterns
that are structurally invisible to text search:
1. ##class(Pkg.Class).Method() explicit cross-class call
2. ..Method() relative-dot self-call (the dominant
intra-class form; large impact on
CALLS completeness)
3. $$$Macro macro expansion via a per-project
table built from .inc files
4. type inference from %New/%OpenId + declared return types
Ensemble production topology (pass_ensemble_routing.c): EnsembleItem
nodes per production component and ROUTES_TO edges resolved from
ProductionDefinition XData, plus WorkMgr .Queue("##class(X).method")
dispatch — all parsed statically at index time, no live IRIS required.
Language detection (language.c): .mac/.int/.rtn map to ObjectScript
routine directly; .cls (shared with Apex) and .inc (shared with BitBake)
are disambiguated by content, defaulting to the existing language on any
doubt so neither Apex nor BitBake detection regresses.
The two new per-project tables (macros, return types) are threaded
through a new internal cbm_extract_file_ex() so the public
cbm_extract_file() signature is unchanged.
The tree-sitter grammars for ObjectScript UDL and routine are vendored
in internal/cbm/vendored/grammars/objectscript_{udl,routine}/ from
https://github.com/intersystems/tree-sitter-objectscript (MIT, ABI 15).
Refs DeusData#462
Signed-off-by: Thomas Dyar <tdyar@intersystems.com>
Two review items applied maintainer-side to save a roundtrip: 1. Restore both vendored ObjectScript scanner.c files to the pristine upstream bytes (a formatter pass had rewritten indentation/braces). Vendored grammar files stay byte-for-byte upstream except for the include repoint documented in MANIFEST.md - style churn breaks upstream diffability on re-vendor. 2. The Studio Export XML sniff in detect_file_language used a raw fopen on a repository path; cbm_fopen keeps it working on non-ASCII Windows paths (project rule, same class as DeusData#996). Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
Register Oracle PL/SQL in lang_specs (packages/types/triggers as Class, procedures/functions as Function, ref_call/branches/assign/raise) and map .pks/.pkb/.pck/.pls/.plb/.plsql/.fnc/.trg/.bdy/.tps/.tpb. Leave .sql and .prc unchanged. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
The ObjectScript/PL/SQL merge left duplicate CBMLanguage values, repeated plsql_* token tables, and twin lang_specs/LANG_NAMES initializer rows. Keep one canonical entry per language so the registry compiles cleanly. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: Oğuz <oguzhan.saricam@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Oğuz <oguzhan.saricam@gmail.com>
dc12e9d to
0b305aa
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Checklist
git commit -s) — required, CI rejectsunsigned commits (DCO, see CONTRIBUTING.md)
make -f Makefile.cbm test)make -f Makefile.cbm lint-ci)