Skip to content

NEA compatibility mode, TAP_SCHEMA.db Oracle fix, deprecation path (3.1.0) - #30

Merged
bjfultn merged 12 commits into
fix/async-detach-without-killing-serverfrom
nea/compat
Oct 6, 2026
Merged

bjfultn merged 12 commits into
fix/async-detach-without-killing-serverfrom
nea/compat

Conversation

@bjfultn

@bjfultn bjfultn commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

This lets the Exoplanet Archive (NEA) deployment run this code line, the one NEID and KOA use, without changing its code or its TAP.conf. NEID and KOA stay byte-identical, except for one Oracle fix every Oracle deployment needs.

It adds a compatibility mode plus a planned path to remove it. Release target: 3.1.0 (minor, because default behavior is unchanged).

1. Fix: TAP_SCHEMA.db sent to Oracle (affects every Oracle deployment)

configparam.py always passes tap_schema_file='TAP_SCHEMA.db', which is SQLite's ATTACH name. Since 4b35392, TableValidator and dataDictionary prefer it over tap_schema. As a result, Oracle receives SELECT … FROM TAP_SCHEMA.db.tables and every query fails with ORA-03048. tap_schema_file is now used only when dbms == 'sqlite3'. main is not affected; every develop-based branch is.

2. Compatibility mode (TAP/compat.py)

Compat mode turns on when TAP.conf uses the 1.x layout ([webserver], a [<dbms>] section, top-level ADQL_*). That layout is translated in memory to the 3.x [WEB]/[DBMS] layout and enables all five behaviors below. A 3.x config can also opt in per behavior with COMPAT = … in [WEB]. Unknown names, or COMPAT outside [WEB], fail at startup.

Name Compat (NEA today) Default (unchanged)
nea-vosi-headers /availability, /capabilities send a status line and CRLF headers body only
nea-errors sync errors are a VOTable error document; a table not in TAP_SCHEMA returns 400 plain text; 403
nea-tables VODataService /tables layout (TAP/compat_vositables.py, the NEA module verbatim) current layout
nea-votable application/xml, no FIELD description/unit for non-char columns text/xml, description and unit
nea-uws <uws:executionDuration>, destruction without Z, application/xml, a bare 303 on job run current form

Each behavior is a single function in compat.py. Call sites call it and contain no if of their own, so removing a behavior later means deleting one function and inlining the default.

3. Deprecation path (MIGRATING.md)

While compat is active, a one-line warning goes to stderr at most once per day (via a stamp file under <workdir>/TAP/; failure never affects a request).

  1. 3.1.0: ships compat mode; NEA installs the wheel with its config unchanged.
  2. NEA moves to the 3.x layout with an explicit COMPAT list. Responses don't change.
  3. Behaviors come off one at a time, once the three archives agree on the target form. Any default-mode change ships in a release whose notes say so, with NEID/KOA sign-off.
  4. 4.0.0: compat mode, COMPAT and the 1.x reader are deleted.

Verification

  • Repo tests: 98 passed, 2 skipped (SQLite fixture), ruff clean. New tests cover the 1.x→3.x key mapping, every compat function in both modes, HTTP-level compat responses from a legacy-config test server, and the once-per-day warning.
  • Differential testing against a containerized replica (RHEL-like image, nginx, Apache CGI, cx_Oracle, Oracle Free loaded with production data). Results on the 18-request smoke corpus, compared byte for byte:
    • Default mode compared with a recording of the base branch plus the TAP_SCHEMA.db fix: 18/18 identical. This is the NEID/KOA no-change check.
    • Compat mode from the unmodified 1.x config, compared with the current NEA production service: 18/18.
    • Explicit COMPAT list in a 3.x config, compared with NEA production: 18/18.
  • Not yet done: a check against the production Oracle 11.2 server (the replica runs Oracle 23ai). That will run on NEA's staging slot before rollout.

Not changed here (for NEID/KOA to decide)

These default-mode gaps were found while measuring. They were left as-is because default mode must not change in this PR: VOSI responses without headers, plain-text errors that pyvo/astroquery can't parse, <uws:executionduration> casing, a Z on local-time destruction, non-standard /tables column elements, and CI that tests only SQLite (how 4b35392 reached develop).

🤖 Generated with Claude Code

bjfultn and others added 12 commits October 6, 2026 10:35
configparam always passes tap_schema_file='TAP_SCHEMA.db', SQLite's ATTACH
name. Since 4b35392 TableValidator and dataDictionary preferred it for every
DBMS, so Oracle got 'FROM TAP_SCHEMA.db.tables' (ORA-03048) on every query.

Co-Authored-By: Claude Haiku 4.5 <[email protected]>
A 1.x TAP.conf ([webserver]/[<dbms>]/ADQL_*) is translated to the 3.x layout
in memory and turns on every NEA compat behavior; a [WEB] config may list
them in COMPAT.  Unknown names fail at startup.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Under nea-uws the 303 that starts a job carries no Content-Type,
Content-Length or Connection line, as bbc1108 prints it; the response ends
when the CGI exits. Default mode bytes are unchanged.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…T only in [WEB]

- nea-uws accepts /async/<id>/executionDuration as bbc1108 did (compat.uws_url_key)
- status.xml is read with either duration spelling, so jobs written under one
  mode survive a switch to the other (compat.duration_value, compat.uws_key)
- COMPAT in any section but [WEB] (including 1.x [webserver]) is a config error

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@bjfultn
bjfultn merged commit e58b9b1 into fix/async-detach-without-killing-server Oct 6, 2026
6 checks passed
@bjfultn
bjfultn deleted the nea/compat branch October 6, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant