Fix JWT authentication for SELECT queries on foreign tables#107
Merged
temuenz merged 2 commits intoJan 28, 2026
Merged
Conversation
The jwt_token was missing from serializePlanData() and deserializePlanData(), causing SELECT queries on foreign tables to fail with JWT authentication. IMPORT FOREIGN SCHEMA worked because it reads options directly, but SELECT uses the serialized plan data where jwt_token was not included. This fixes the "cannot authenticate" error (line 99) when using JWT auth for queries on foreign tables.
When JWT auth is used, user is NULL. But db2GetSession converts NULL to "". Meanwhile insertconnEntry stores "" as NULL. This caused findconnEntry to fail matching: - Stored: step->uid = NULL - Searching: user = "" - Old code: NULL == "" -> false (no match!) Now both NULL and "" are treated as "empty" and match each other.
Contributor
Author
|
@temuenz Hi Thomas, is it possible you have a look ? Thank you. |
Collaborator
|
I merged your code. Last time I ran the pipeline it all worked. |
temuenz
added a commit
that referenced
this pull request
Jan 28, 2026
temuenz
added a commit
that referenced
this pull request
May 17, 2026
* #105 Introducing db2GetForeignUpperPaths * add deep copy of fdwstate for upper path * added deparseAggref to handle aggregate functions count, sum, min, max, avg * the code is able now to correctly parse the aggregate functions, but still issues with the result passed back to PG * enhanced traces * still not working properly. refer to pg_fdw for clarification. * reworks all the depare functions to match the pg_fdw implementation more closely * removed all code no longer required by PG >= v13 * added some later PG_VERSION_NUM sections for compatibility of the code vor PG 13-18 * moved deparse functions from db2_fdw_utils to db2_deparse * adding more parsing functions * add fetchsize to the fdw * fix warn on cast SQLULEN to SQLPOINTER * adding fetchsize to fdwState (de)serializing * addinf fetch_size to fdwState (de)serializing * more preparations for push down of aggregates * just define FIXED_FETCH_SIZE * added debug tracing * save the old file just in case we need to revert quickly * added retrieved_attr list * factor out de/serializatin of plan to a new file * factor our de / serialization of plan data * rework of building the foreign plan * more deparsing rework * adding JWT Token to de / serialization of fdw_state * follow up #107 change in this branch * more preparations for push down of aggregate functions * the repo has moved to pg-fdw * Update documentation to reflect correct GitHub URL and author email * first working version of aggregate push down * refactor convertTuple to simply iterate over the expected results and in that change db2GetLob to use DB2ResultColumn instead of DB2Column * remove columnindex from DB2FdwState since it is no longer used * if ever, this new will be version 18.2.0 * enhanced debug output * solved the problem of multiple columns in an aggregate function as well as ensured the result for count is always a big integer * enhanced debugging output * fixed the test for an expression is a column of any of the relations used in the query * handle NULLs correctly * remove the reverting of the resulnumber. The aim now is to ensure the resnumber is correctly set to the position of the result in the query. * removed pgtype and directly used res->pgtype * started to set resnum correctly, but on foreignjoinpaths the way the foreignrel->reltarget-expr is populated in reverse to the query sequence * enhanced Debug Traces * ensure the result columns are correctly sorted as mentioned in the query that is sent to the foreign server * use the correct db2PrepareQuery Prototype * cleanup the code formatting * cleanup code * adding relevant binding parameters to ParamDesc so it can be bound without the reference to DB2Column * more dead code cleanup * add pathnodes.h to ensure elements if DB2FdWState are resovable wherever used. * rearrange the sequence of options sources to reflect the order of precedence * define PQ_QUERY_PARAM_MAX_LIMIT if not defined yet * aligned the code more with how postgres_fdw does it * removed foreign.h and pathnodes.h since they are included in DB2FdwState.h now * enhance debug tracing * enhance debug tracing * when one column signals inclusion of all colums the logic was not coping with that - it is now. * enhanced debug tracing * renaming Db2Column.varno to pgrelid which is the index of the relation in the query (e.g. in joins 1., 2., .. table) * proper formatting of pointers * actually for analyze we seem not to be needing any results. The code generates a dummy result capture which is sufficient. * fixed a typo in debug output * add all the db2 column attributes to the fdw column option. with that we ought to be able to no longer need to db2Describe the table(s) in use at the begining of a query and safe those roundtrips to the DB2 catalog. * remove OLD_FDW_API precompile exclusions from the code * adding db2bytes and db2chars as fdw column options * reworked ImportForeignSchema that adds all necessary db2 column info into FDW options * code cleanup * added a compiler error when using PG < 13 * rncols no longer required * cleanup code * first try the new way of describing the fdw table if that fails use the old way * the function has been added to db2GetFdwState, as it is only used there * db2Getoptions.c has become obsolete * code and debug beautifying * oops forgot to move optionIsTrue - now in db2_fdw_utils.c * prepare DirectModify Function for UPDATE and DELETE * ensure the value of serialized and deserialized FDWState is printed at debug level 3 * still trying to get the Update to work but the junkres does not bear the correct value yet * complete rework of the debug tracing functions * migration of debug tracing to macros defined in db2_fdw.h * direct update and direct delete now work, but the code is likely not final yet * instead of allocating indentation, just move the output in the outputbuffer * adding comments to functions * estate and rtinfo are currently not used in db2IterateDirectModify, but probably later, so just commented out for the time being * using db2alloc instead of palloc * adding a debug trace before freeing resCol * on insert we lost the input value of the key, so adding to look for it in the slot attribute if it was not set in resjunk * fix a debug message * simply use the Key Column name for the junkresname as well, it seems to have no impact * ensure junk attrs are only obtained on UPDATE and DELETE. Obtain the attrno by Calling by column name, since we used that on AddUpdateTargets. * obtaining junk attr values is now easy by simple using pkey value. * refactored convertTuple to call it from functions using both DB2FdwState and DB2FdwDirectModifyState * added proper return of affected rows * fail on error when deployed to an too old pg version (<13) * introduced PG_SUPPORTED_MIN_VERSION * ensure the code compiles for PG 13 thru 18 * moving the includes for pure sqlcli functions to db2_fdw.h * adding db2Log, db2LogInfo, db2LogNotice, db2LogWarning and db2LogError functions to enhance debug tracing * completed prototype for the debugging functions. * removed more pre PG V13 defines * changed memory management functions in code to use macros for better debug tracing * fixing query like "select empno, firstnme,lastname, salary + bonus + comm from sample.employee where salary > 8000 and lastname like 'L%';" * porting fixes for #110, #111, #112 and #113 into this branch * modularize the testing * TC001: Dropping and re-creating a foreign table "manually" * TC002: Importing a single foreign table from a remote schema * TC003: Run a simple join * TC004: clone a foreign table into a local table including content * TC005: run a pushdown query for aggregate functions * test results * update license and remove LivingMainframe from it * fixing TC007 * new testcases added * fixing push down LIMIT n OFFEST m; * extending TC011 * enhanced testcases * enhanced push down order by limit offset * more tests * reword fdw options and follow up on documentation * update doc * current testresult
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.
Summary
Fixes JWT authentication issues that caused SELECT queries on foreign tables to fail while IMPORT FOREIGN SCHEMA worked correctly.
Changes
Add jwt_token to plan serialization/deserialization (
db2PlanForeignModify.c,db2BeginForeignModify.c)jwt_tokenwas missing fromserializePlanData()anddeserializePlanData()Fix connection cache lookup (
db2AllocConnHdl.c)insertconnEntry()stores empty string as NULLdb2GetSession()converts NULL to empty stringfindconnEntry()now treats NULL and empty string as equivalentSymptoms fixed
cannot authenticateerror (line 99) when using JWT auth for SELECTdb2EndTransaction internal error: handle not found in cachePANIC: ERRORDATA_STACK_SIZE exceededTesting