MangoCode

MangoCode

@mangocode.bsky.social

Oracle APEX developer. Oracle ACE Apprentice 🥭 Sharing real problems, real solutions. MangoCode = Mangoensentono

16 followers4 following340 posts

Had an Oracle APEX Interactive Grid that forgot its checkboxes after every refresh. Worked through it with GitHub Copilot. Three fixes, all plausible, none of them worked. The bug was somewhere else entirely.

View full thread

The root cause is in APEX's own source. It defines its own pageChange in the grid options and passes those after yours, so a pageChange in defaultGridViewOptions never runs. Listening to the gridpagechange event on the grid view works.

Had an Oracle APEX Interactive Grid that forgot its checkboxes after every refresh. Worked through it with GitHub Copilot. Three fixes, all plausible, none of them worked. The bug was somewhere else entirely.

View full thread

Every Copilot fix changed when the restore ran. None of them made it run after every refresh, so the guard stayed up and real clicks were thrown away too.

One console.log at the start of the save function showed it: right ID, guard still up. The first click never reached the server. We had been fixing the second step.

Had an Oracle APEX Interactive Grid that forgot its checkboxes after every refresh. Worked through it with GitHub Copilot. Three fixes, all plausible, none of them worked. The bug was somewhere else entirely.

View full thread

Showing a row and ticking its checkbox are separate in an Interactive Grid. The query can return the row again after a refresh, but the grid does not know it should be ticked. So you keep the IDs yourself and put the ticks back.

To stop a refresh from wiping the saved set, a guard ignores selection events while the grid refreshes. Something has to lower that guard after every refresh. In this design, that is the restore itself.

Had an Oracle APEX Interactive Grid that forgot its checkboxes after every refresh. Worked through it with GitHub Copilot. Three fixes, all plausible, none of them worked. The bug was somewhere else entirely.

The use case is common: a long list, a filter that narrows it, and users who want to build one selection across several filter values instead of scrolling the full list.

I spent my Friday night typing Dutch into the new APEX 26.2 Interactive Report search bar. The assistant told me it had filtered my report. The report said "No data found." Here is the whole story, in English and Dutch on the same data.

View full thread

What I could not fix: grouping. "what is the total amount per category" errors in English and Dutch. The user sees "An unexpected error occurred." The real ORA-20960 is in debug only. If you made it work, I would love to hear how.

I spent my Friday night typing Dutch into the new APEX 26.2 Interactive Report search bar. The assistant told me it had filtered my report. The report said "No data found." Here is the whole story, in English and Dutch on the same data.

View full thread

Then I set the application language to Dutch. "filter status op Afgerond" ran locally and "opnieuw instellen" reset the report, the same words as the reset button. The English phrase stopped working. Finding the other Dutch phrases is trial and error for now.

With AI search on, input of 3 words or more goes to the model and shorter input stays a row search. The 26.1 docs say something different, so I trust what I saw.

I spent my Friday night typing Dutch into the new APEX 26.2 Interactive Report search bar. The assistant told me it had filtered my report. The report said "No data found." Here is the whole story, in English and Dutch on the same data.

View full thread

In a default English application, English key phrases work on Dutch column names and values. "filter status by Afgerond" and "break on categorie" both did exactly what they should. Values with a space need quotes.

Dutch commands do not match there. "filter status op Afgerond" becomes a text search for the whole sentence and returns nothing. A user will not think their command was wrong. They will say the search is broken.

I spent my Friday night typing Dutch into the new APEX 26.2 Interactive Report search bar. The assistant told me it had filtered my report. The report said "No data found." Here is the whole story, in English and Dutch on the same data.

26.2 adds key phrases to the search bar. "filter status by Completed" and APEX applies the filter itself. I checked the debug log to be sure: no AI call, no tokens. That part is lovely.

Spent some time trying to make my own APEX app leak data with the new AI assistant in 26.2. Logged in as Bob, I asked for Alice's order 1001, and the careless version I wrote gave me a working link. Thread on what I found.

View full thread

I would also like to know how far an agent that reads data and renders markdown links is exposed to indirect prompt injection. My test agent reads nothing, so I could not test it. If you have tried it on 26.2, I would love to hear what you saw.

Spent some time trying to make my own APEX app leak data with the new AI assistant in 26.2. Logged in as Bob, I asked for Alice's order 1001, and the careless version I wrote gave me a working link. Thread on what I found.

View full thread

The careful callback checks the ID is a number and that the order belongs to the current user. Same question, five refusals out of five.

Two side findings. "Open order -1" only failed because the fetch returned no rows (ORA-01403), which is luck and not a control. And the model sometimes wrote order_id in lowercase, which APEX does not match, so I saw raw placeholders on some runs.

Spent some time trying to make my own APEX app leak data with the new AI assistant in 26.2. Logged in as Bob, I asked for Alice's order 1001, and the careless version I wrote gave me a working link. Thread on what I found.

View full thread

The careless callback passed the model's ID into APEX_PAGE.GET_URL, which signs it with a valid checksum. Bob clicked and read "Confidential merger fee". Five runs out of five.

The page was a form, so it was a write as well. I changed the notes field as Bob and it saved. A read leak on a form page is a write leak.

Spent some time trying to make my own APEX app leak data with the new AI assistant in 26.2. Logged in as Bob, I asked for Alice's order 1001, and the careless version I wrote gave me a working link. Thread on what I found.

View full thread

The model writes a placeholder, and APEX calls a PL/SQL callback you write. Oracle's docs say it directly: "the navigation callback is the application security boundary."

Before any AI, I checked that typing Alice's order ID into the URL by hand fails. It did, with SSP_CHECKSUM_MISSING. So a later leak would have to come from the AI path.

Spent some time trying to make my own APEX app leak data with the new AI assistant in 26.2. Logged in as Bob, I asked for Alice's order 1001, and the careless version I wrote gave me a working link. Thread on what I found.

The design is nice. You define navigation targets, and the model only sees IDs, hints and parameters. No URL, no session ID, no checksum ever reaches it.

A UAT tester reported that some of their selected rows never got processed. No App Builder in UAT, so I could not look. A thread on what I built, what I learned afterwards, and what the bug actually was.

View full thread

For a session only someone else can reproduce, APEX_SESSION.SET_DEBUG switches debug on for them, and APEX_DEBUG_MESSAGES gives you the trace as a plain query.

A UAT tester reported that some of their selected rows never got processed. No App Builder in UAT, so I could not look. A thread on what I built, what I learned afterwards, and what the bug actually was.

View full thread

So I put the query in a report region on the page, where it does run inside the session, and made it visible only in debug mode. Condition: PL/SQL Expression, apex_application.g_debug.

Then I remembered about APEX_SESSION.ATTACH. Session ID from the URL, attach from SQL Developer, and apex_collections returns what that session holds. I tried it on my own session afterwards and it is now the first thing I would reach for.

A UAT tester reported that some of their selected rows never got processed. No App Builder in UAT, so I could not look. A thread on what I built, what I learned afterwards, and what the bug actually was.

The selected rows go into an APEX collection, and a cursor joins it to two tables. In DEV the collection had every ID, so the rows had to be dropping out in one of the joins.

Running the cursor in SQL Developer was not an option. A collection only exists inside the APEX session, and SQL Developer opens its own session, where the collection is simply empty.

Six ways to fire many REST calls at once from inside an Oracle database, with working code for each. Four of them turn out to be the same mechanism wearing different names, which changes what the choice is actually about.

View full thread

Working code for all six, the traps in each, and what they are actually for. If you run any of it and get different numbers I would like to hear, particularly on the parallel hint, which did not reproduce consistently for me at all. www.mangocode.dev/six-ways-to-... #OracleAPEX #PLSQL #Oracle #AI

mangocode.devSix ways to fire many REST calls at once from Oracle, and how to pick oneLast time I wrote about this I had four mechanisms and a ranking: I saw a Go program fire twenty AI calls at once. Could I do that in PL/SQL?. Now I have six mechanisms and no ranking, because when I ...

Six ways to fire many REST calls at once from inside an Oracle database, with working code for each. Four of them turn out to be the same mechanism wearing different names, which changes what the choice is actually about.

View full thread

195 real embedding calls, 8 workers requested, timed first row start to last row end so no mechanism is charged for its own submission overhead: DBMS_AQ 7.74x APEX background chains 7.29x DBMS_PARALLEL_EXECUTE 7.09x DBMS_SCHEDULER 6.87x

Since throughput does not separate them, pick on shape. A known batch of rows: DBMS_PARALLEL_EXECUTE. Work that is not rows, or a split you want to control yourself: DBMS_SCHEDULER. Requests arriving one at a time from different users: DBMS_AQ, because there is nothing to chunk.

Six ways to fire many REST calls at once from inside an Oracle database, with working code for each. Four of them turn out to be the same mechanism wearing different names, which changes what the choice is actually about.

Everything follows from one constraint: PL/SQL has no asynchronous HTTP. UTL_HTTP and APEX_WEB_SERVICE block the calling session for the entire round trip. One session holds exactly one REST call in flight, so twenty at once needs twenty sessions, and every way of getting them is job-based.

Which is why four of the six are architecturally identical. DBMS_PARALLEL_EXECUTE creates DBMS_SCHEDULER jobs. APEX background chains wrap DBMS_SCHEDULER. A DBMS_AQ consumer pool is DBMS_SCHEDULER jobs. Four APIs drawing on one pool of job slaves, bounded by the same JOB_QUEUE_PROCESSES.

Someone built a small Go tool that fires twenty AI image calls simultaneously instead of one at a time. Half an hour of generating becomes about a minute. I wanted to know whether Oracle could do the same thing from inside the database. Thread on what I found.

View full thread

Then the parallel hint approach, using PX query slaves rather than jobs. With DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDING inside it the session never came back. No error, no timeout, no ORA number because no row got far enough to write one. Killed it by hand after 65 minutes.

Full write-up with the code for every mechanism, how I measured concurrency without sampling V$SESSION, why the Autonomous service name in your connection string decides your degree of parallelism, and what all this costs you in held sessions. www.linkedin.com/pulse/i-saw-... #PLSQL #Oracle #AI

linkedin.comI saw a Go program fire twenty AI calls at once. Could I do that in PL/SQL?Someone posted a small Go tool called imagine-cli. It generates images from the command line, and its selling point is that it does not do them one at a time.

Someone built a small Go tool that fires twenty AI image calls simultaneously instead of one at a time. Half an hour of generating becomes about a minute. I wanted to know whether Oracle could do the same thing from inside the database. Thread on what I found.

View full thread

Benchmarked on real embedding calls rather than images, which would have cost too much to repeat. 195 rows, 8 workers requested: Sequential 68.7s DBMS_SCHEDULER 11.1s, 6.07x DBMS_PARALLEL_EXECUTE 12.4s, 5.06x

Someone built a small Go tool that fires twenty AI image calls simultaneously instead of one at a time. Half an hour of generating becomes about a minute. I wanted to know whether Oracle could do the same thing from inside the database. Thread on what I found.

The constraint everything follows from: PL/SQL has no asynchronous HTTP. UTL_HTTP and APEX_WEB_SERVICE block the calling session for the entire round trip. No callback, no handle you can check back on later. One session can hold exactly one REST call in flight.