Upgrading
Applying a new release is not the same procedure as a first install: the schema already has your documents in it, and the goal is to replace code without touching data.
This page is the procedure. What each release actually changed is in its own page — What changed in 26.1 — and it is worth reading before you run anything.
Before you start
Section titled “Before you start”Stop the traffic you can. The install replaces package bodies while sessions may be running
against them, which surfaces as ORA-04068 for whoever is mid-action. A short maintenance window
avoids a support call.
Why there are migration scripts at all
Section titled “Why there are migration scripts at all”install.sql creates tables with a plain create table. On an existing schema that raises
ORA-00955 and changes nothing — which is exactly right for a table that already exists, and
exactly wrong for a table that needs a new column or a changed constraint. That, plus data
backfills, is what the migration scripts are for. Everything else — packages, views, macros,
triggers, new tables, new indexes, new jobs — arrives with install.sql on its own.
Upgrading to 26.1
Section titled “Upgrading to 26.1”Seven steps, in this order. Run all of them as the ADM schema owner.
-
Schema changes.
Terminal window sqlplus adm/password@db @scripts/migrations/26.1/26.1_pre.sqlPrints one line per step, prefixed
create,update,exists,skiporWARNING. Read the warnings — see What the warnings mean below. Nothing here is fatal.The last step gathers optimiser statistics on the tables it changed. On a schema with millions of documents that takes minutes rather than seconds; it is also the only step in the whole upgrade you can safely skip, if you would rather gather them in a window of your own. Comment the block out and nothing else is affected — the plans simply take until the next automatic statistics window to catch up.
-
The base product.
Terminal window sqlplus adm/password@db @install.sql # logs to install_adm.logThis log will contain errors, and most of them are expected on an upgrade. See Reading the install log.
-
Data backfill.
Terminal window sqlplus adm/password@db @scripts/migrations/26.1/26.1_post.sqlThis is the one that repairs the trash, clears the accidental share-link passwords, and seeds the settings an upgrade cannot get from
install.sql. It ends by re-checking the trash invariant and telling you whether it holds. -
Dependency cleanup.
Terminal window sqlplus adm/password@db @scripts/migrations/26.1/26.1_deps_post.sql26.1 upgrades APEX Office Print and APEX Office Edit. This removes superseded AOP package generations and recompiles the bundled dependencies. If it reports incomplete or invalid AOP targets, correct the installation errors and re-run this step; no packages are dropped until all three AOP synonyms resolve to valid packages of the same generation.
-
AI Pack schema changes — skip steps 5 to 7 entirely if you do not have the AI Pack.
Terminal window sqlplus adm/password@db @scripts/migrations/26.1/26.1_ai_pre.sql -
The AI Pack.
Terminal window sqlplus adm/password@db @install_ai.sql # logs to install_adm_ai.log -
AI Pack reconcile.
Terminal window sqlplus adm/password@db @scripts/migrations/26.1/26.1_ai_post.sqlOn a Qdrant-only installation this reconciles nothing and says so, which is the correct outcome. On one with
vector_store: "ORACLE"collections it rebuilds each vector index once.
Then the two things that are not SQL:
-
Re-import the APEX application from the release’s
f215.sql, overwriting the existing application ID. -
Re-license the plug-ins if the release brought new ones. Existing licences in
uc_pluginspro_licenseare untouched by the install; a plug-in added in a new release needs its ownuc_pluginspro.auto_licensecall — see Installation, step 3.26.1 brings no new plug-in dependency, so there is nothing to do here for this release.
Verifying
Section titled “Verifying”Three checks, in increasing order of how much they tell you.
1. Nothing is invalid
Section titled “1. Nothing is invalid”select object_type , object_name from user_objects where status = 'INVALID' order by object_type , object_name;The expected answer is no rows. If a body is invalid, compile it and read the errors:
alter package adm_document_api compile body;select * from user_errors where name = 'ADM_DOCUMENT_API';2. The product works
Section titled “2. The product works”Log in, open a folder, download a file, upload a new version, rename something with a space in the name, and run a full-text search. Then look at a document in the trash: it should show its real name, and restoring it should put it back where it came from.
3. The jobs work
Section titled “3. The jobs work”Check the job log
after the next daily run. A maintenance procedure that fails there surfaces nowhere else. With
the AI Pack, ADM_AI_RAG_QUEUE_JOB runs every five minutes, so you do not have to wait long for
its first result — and expect the first few runs after the upgrade to be busy, because they work
through the REMOVE jobs that previous versions queued and never consumed.
Reading the install log
Section titled “Reading the install log”install.sql runs with whenever sqlerror continue, because an upgrade has to walk past the
errors that mean “this already exists”. That makes the log noisy, and it makes an unexpected
error easy to miss.
These are expected on an upgrade and mean nothing was overwritten:
| Error | What it means |
|---|---|
ORA-00955: name is already used | A table, index or sequence that already exists. By far the most common — around 100 of them |
ORA-00001 / ORA-03301 | A seed row that already exists: the roles, the root folders, the settings, the hooks |
ORA-02275: such a referential constraint already exists | A foreign key that already exists |
ORA-27477: ... already exists | A scheduler job that already exists |
ORA-20000 with DRG-10507: duplicate index name | The Oracle Text indexing policy already exists |
PLS-00201 on a package specification, followed by that package compiling later | Specs are installed in file order, so one can briefly reference another that has not been created yet. The final state is what counts — check step 1 of Verifying, not the log |
So the useful filter is this, and anything it prints deserves a look:
grep -E "^(ORA|PLS|DRG)-" install_adm.log \ | grep -vE "ORA-00955|ORA-00001|ORA-03301|ORA-02275|ORA-27477|DRG-10507"Do the same for install_adm_ai.log.
What the warnings mean
Section titled “What the warnings mean”The migration scripts report WARNING for things that completed but left you something to look
at. None of them stops the upgrade.
“N existing row(s) do not satisfy it - rename them” — a folder, document, user or group name in your data contains a character that is now refused. The constraint was added without validating existing rows, so nothing broke and nothing was deleted; but such a row cannot be updated until the name is fixed. Find them with the condition named in the message, for example:
select folder_id, folder_name, folder_path from adm_folders where regexp_like(folder_name, '[[:cntrl:]<>:"/|?*]') or instr(folder_name, '\') > 0;“N password-protected link(s) still hold a pre-26.1 hash” — expected, and not a problem. Each one upgrades itself the next time somebody opens it with the correct password. To retire them sooner, delete and reissue those links.
“N collection(s) do not satisfy the new form” (AI Pack) — a collection name contains a
character that is now refused because it reaches the Qdrant REST path. Such a collection keeps
working for reads but cannot be updated through the API at all, because
update_rag_collection writes the name back whether you changed it or not. Rename it with a
direct update, rename the matching Qdrant collection, or recreate the collection.
“trashed folder(s) without a trash root … review these by hand” — the trash backfill found
rows it could not classify, most likely because a folder_path was edited by hand at some
point. The upgrade completed; these rows need a decision from you.
“FAILED: …” on a vector index (AI Pack) — the vector pool was never sized. That collection
was already running without an index and every search on it was an exact scan; you can now see
it. Set VECTOR_MEMORY_SIZE, or configure vector_index.type: "IVF", which needs no pool.
Re-running a migration script
Section titled “Re-running a migration script”All five 26.1 scripts are idempotent. A second run finds every step already done and reports
exists for it. That is deliberate, and it is what makes them safe to use when you are not
certain which release a schema is on, or when a deployment is retried after a network drop.
If a script does stop with an error, fix the cause and run the whole script again — not the part after the failure. The DDL steps commit as Oracle always does; the data steps are held until the final commit, so a failure half way leaves no half-done data change behind.
What survives an upgrade, and what does not
Section titled “What survives an upgrade, and what does not”| Survives | Does not survive |
|---|---|
| All data: documents, versions, folders, users, groups, shares, tags, audit log | Any modification you made to an ADM package, table or view |
Settings values in adm_settings — a value you changed is yours, and only the description, category and recorded default are refreshed | Any modification you made inside the APEX application |
Hook PL/SQL registered in adm_hooks | — |
Plug-in licences in uc_pluginspro_license | — |
| Your own tables, and your own code that calls ADM’s APIs | — |
Your own code calling ADM’s documented APIs is expected to keep working. The
API reference is the contract; anything marked
@private in it is not, and may change between releases without notice.
Upgrading from a release older than 0.1.6
Section titled “Upgrading from a release older than 0.1.6”Apply each release’s migration scripts in version order, then 26.1’s. The directories are under
scripts/migrations/, one per release, and each script’s header says whether it runs before or
after install.sql.
You only need install.sql once, at the end — the intermediate releases’ code is superseded
by 26.1’s. The pre-install scripts of the older releases can therefore all be run first, in
order, followed by install.sql, followed by the post-install ones in the same order. If you
would rather not reason about that, running each release’s full sequence in turn also works and
is slower.