Skip to content

Commit

Permalink
Squash commits of devel branch DEV_0_6_0 in preparation for release R…
Browse files Browse the repository at this point in the history
…EL0_6_0.

commit 0357237df15ffe16e4a73ca5835143d1973afa63
Author: Bernd Helmle <[email protected]>
Date:   Sat Aug 5 14:10:03 2023 +0000

    Follow up fix for issue credativ#31.

    Commit 285119f partially fixed our
    architecture thinko regarding query planning, but it turned out
    that we have the same issue in ifxGetForeignRelSize(). The former
    idea was to cache all informix objects created during the planning phase
    for execution later, since we rely on query statistics by using
    the query descriptors. We created them in ifxGetForeignRelSize() and
    reused these objects in ifxPlanForeignModify() later.

    But ifxGetForeignRelSize() isn't necessarily called, so ifxPlanForeignModify()
    needs to take care whether the objects are usable directly or still need
    to be created.

    I just copied the code from ifxGetForeignRelSize() without moving it into
    a dedicated function, which fixes the problem. It might be more pretty
    to have it in a dedicated function, but leave it as-is for now.

    Regression tests are extended to have trigger tests as described in
    issue credativ#31.

commit db73ab94c94d77d3d56590933c7a3dd1c66d1f5a
Author: Bernd Helmle <[email protected]>
Date:   Mon Jul 24 16:37:43 2023 +0000

    Fix longstanding bug in issue credativ#31.

    The issue describe here

    httpg://github.com/credativ/issues/31

    uncovered an unfortunate mistake in our approach on how
    we plan a modify action. Formerly, ifxPlanForeignModify() was
    also responsible to create and execute the necessary query objects
    on the remote Informix server (like describing the statement and thus
    creating the required SQLDA structure).

    In this issue above it turned out that we are far too optimistic in
    doing this preparation work at this early stage: ifxPlanForeignModify() might not
    be called once a prepared statement settles the execution plan and thus
    we miss important things like creating and describing the statement handles.

    To fix this, we need to delay creating of query objects on the remote
    Informix server to ifxBeginForeignModify(), which is now responsible
    to create and describe the statement.

    ifxPlanForeignModify() still creates all required identifiers for
    query objects (like cursor, statement handle, ...), but this leaves
    us after the plan settled with a static reference counter (refid) used
    in the identifiers.
    I think this isn't a problem here, since afaics the refid can't be reused
    somewhere else at this point. This might be wrong, but since we pass
    regression tests at this point i leave it for now.

commit 3fdfab57056c454738c99279f1d9dbfad5e9c0e0
Author: Bernd Helmle <[email protected]>
Date:   Thu Jul 20 16:41:31 2023 +0000

    Update and correct README.

commit b2798e3f4866c851dc20dc4d0109d66f58dda3dc
Author: Bernd Helmle <[email protected]>
Date:   Thu Jul 20 16:07:41 2023 +0000

    Fix copy&paste error.

commit 67eed75976efa40f17b5452b373fb732ed088c11
Author: Bernd Helmle <[email protected]>
Date:   Thu Jul 20 15:56:46 2023 +0000

    Follow up commit for backward compatibility.

    HASH_STRINGS is available as dynahash flag beginning with PG14,
    so handle it accordingly.

commit ab2b38f5fd714acced49c9c6bac2a462a977d76d
Author: Bernd Helmle <[email protected]>
Date:   Thu Jul 20 10:21:08 2023 +0000

    Fix compile issues caused by changes made for PG16 support.

commit 1f71169f36d121260ec4b27c106d54c04ca4e24a
Author: Bernd Helmle <[email protected]>
Date:   Thu Jul 20 09:59:12 2023 +0000

    Support PostgreSQL 16.

    Including commit 76a08e2 this introduces
    support for the upcoming new major release 16 of PostgreSQL.

    Commit a61b1f74823c9c4f79c95226a461f1e7a367764b reworked the relation
    permission checking infrastructure in PostgreSQL which forces us to cope
    with them properly.

    No new features yet and needs testing against all supported older
    major releases (as of this commit these are 10, 11, 12, 13, 14, 15).

commit fc137b2c258ecc21cc1290da33417b04780abf5f
Author: Bernd Helmle <[email protected]>
Date:   Thu Jul 20 09:56:01 2023 +0000

    Make HASH_STRINGS in connection cache explicit.

    Starting with PostgreSQL 16 dynahash's implementation forces
    explicit usage of HASH_STRINGS when creating the hash table we use
    for storing Informix connection handles. Since the lookup key is the
    connection identifier composed by strings up to IFX_CONNAME_LEN, we
    must set HASH_STRINGS accordingly, otherwise we run into an
    assertion failure.
  • Loading branch information
psoo committed Aug 11, 2023
1 parent 01a34d7 commit b518b08
Show file tree
Hide file tree
Showing 5 changed files with 539 additions and 64 deletions.
53 changes: 22 additions & 31 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -121,44 +121,35 @@ your Client SDK installation (e.g. $INFORMIXDIR/etc/sqlhosts and
the Informix FDW can be used as follows, assumed you have an Informix
connection named 'centosifx_tcp':

```sql
CREATE EXTENSION informix_fdw;

CREATE SERVER centosifx_tcp
CREATE SERVER test_server
FOREIGN DATA WRAPPER informix_fdw
OPTIONS (informixserver 'centosifx_tcp');
OPTIONS (informixserver 'informix', informixdir '/opt/informix/csdk');

CREATE USER MAPPING FOR CURRENT_USER
SERVER centosifx_tcp
SERVER test_server
OPTIONS (username 'informix', password 'informix');

CREATE FOREIGN TABLE foo (
id integer,
value integer
)
SERVER centosifx_tcp
OPTIONS ( query 'SELECT * FROM foo',
database 'test',
informixdir '/Applications/IBM/informix');

CREATE SERVER sles11_tcp
FOREIGN DATA WRAPPER informix_fdw
OPTIONS (informixserver 'ol_informix1170');

CREATE USER MAPPING FOR CURRENT_USER
SERVER sles11_tcp
OPTIONS (username 'informix', password 'informix');

CREATE FOREIGN TABLE foo (
id integer,
value integer
)
SERVER sles11_tcp
OPTIONS ( query 'SELECT * FROM foo',
database 'test',
db_locale 'en_us.819',
client_locale 'en_US.utf8',
informixserver 'ol_informix1170',
informixdir '/Applications/IBM/informix');
CREATE FOREIGN TABLE inttest(f1 bigint not null,
f2 integer,
f3 smallint)
SERVER test_server
OPTIONS(table 'inttest',
client_locale 'en_US.utf8'
db_locale 'en_US.819',
database 'regression_dml');
```sql

The settings `informixdir` and `informixserver` are dependent on your
installation and configuration. `db_locale` and `client_locale` must be
specified to enable correct conversion between foreign Informix and local PostgreSQL server.

`table` identifies the table on the remote Informix server you want to access. There
is also the `query` parameter in the example above, which can be used to access
the remote data in a view-like manner. For more detailed information about options
read the FDW Options section below.

= Supported datatypes =

Expand Down
182 changes: 182 additions & 0 deletions expected/informix_fdw_tx_1.out
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,188 @@ COMMIT;
--
ALTER FOREIGN TABLE inttest OPTIONS(DROP disable_rowid);
--------------------------------------------------------------------------------
-- Tests for PREPARE
--
-- See discussion in github issue
-- https://github.com/credativ/informix_fdw/issues/31
--------------------------------------------------------------------------------
--
-- INSERT
--
BEGIN;
PREPARE ins_inttest(bigint) AS INSERT INTO inttest VALUES($1);
EXECUTE ins_inttest (1);
EXECUTE ins_inttest (2);
EXECUTE ins_inttest (3);
EXECUTE ins_inttest (4);
EXECUTE ins_inttest (5);
EXECUTE ins_inttest (6);
EXECUTE ins_inttest (7);
COMMIT;
DEALLOCATE ins_inttest;
--
-- UPDATE
--
BEGIN;
PREPARE upd_inttest(bigint) AS UPDATE inttest SET f1 = f1 WHERE f1 = $1;
EXECUTE upd_inttest (1);
EXECUTE upd_inttest (2);
EXECUTE upd_inttest (3);
EXECUTE upd_inttest (4);
EXECUTE upd_inttest (5);
EXECUTE upd_inttest (6);
EXECUTE upd_inttest (7);
COMMIT;
DEALLOCATE upd_inttest;
--
-- DELETE
--
BEGIN;
PREPARE del_inttest(bigint) AS DELETE FROM inttest WHERE f1 = $1;
EXECUTE del_inttest (1);
EXECUTE del_inttest (2);
EXECUTE del_inttest (3);
EXECUTE del_inttest (4);
EXECUTE del_inttest (5);
EXECUTE del_inttest (6);
EXECUTE del_inttest (7);
COMMIT;
DEALLOCATE del_inttest;
--------------------------------------------------------------------------------
-- Trigger Tests
--------------------------------------------------------------------------------
BEGIN;
CREATE TABLE IF NOT EXISTS delete_fdw_trigger_test(id bigint primary key);
--
-- A before trigger testing before actions on INSERT/UPDATE/DELETE
-- on a foreign table
--
CREATE OR REPLACE FUNCTION f_tg_test()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
BEGIN
IF TG_OP = 'DELETE' THEN
DELETE FROM inttest WHERE f1 = OLD.id;
RETURN OLD;
ELSIF TG_OP = 'UPDATE' THEN
UPDATE inttest SET f1 = NEW.id WHERE f1 = OLD.id;
RETURN NEW;
ELSIF TG_OP = 'INSERT' THEN
INSERT INTO inttest VALUES(NEW.id);
RETURN NEW;
ELSE
RAISE EXCEPTION 'unhandled trigger action %', TG_OP;
END IF;
END;
$$;
--
-- A broken trigger function referencing the wrong tuple identifiers
-- according to the trigger action (NEW vs. OLD)
--
-- Basically the same as above.
--
CREATE OR REPLACE FUNCTION f_tg_test_broken()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
BEGIN
IF TG_OP = 'DELETE' THEN
DELETE FROM inttest WHERE f1 = NEW.id;
RETURN OLD;
ELSIF TG_OP = 'UPDATE' THEN
UPDATE inttest SET f1 = NEW.id WHERE f1 = OLD.id;
RETURN NEW;
ELSIF TG_OP = 'INSERT' THEN
INSERT INTO inttest VALUES(OLD.id);
RETURN NEW;
ELSE
RAISE EXCEPTION 'unhandled trigger action %', TG_OP;
END IF;
END;
$$;
CREATE TRIGGER tg_inttest
BEFORE DELETE OR UPDATE OR INSERT ON delete_fdw_trigger_test
FOR EACH ROW EXECUTE PROCEDURE f_tg_test();
TRUNCATE delete_fdw_trigger_test;
INSERT INTO delete_fdw_trigger_test VALUES(1), (2), (3);
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
1 | |
2 | |
3 | |
(3 rows)

DELETE FROM delete_fdw_trigger_test WHERE id = 2;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
1 | |
3 | |
(2 rows)

UPDATE delete_fdw_trigger_test SET id = 4 WHERE id = 3;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
1 | |
4 | |
(2 rows)

INSERT INTO delete_fdw_trigger_test VALUES(5);
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
1 | |
4 | |
5 | |
(3 rows)

DELETE FROM delete_fdw_trigger_test;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
(0 rows)

DROP TRIGGER tg_inttest ON delete_fdw_trigger_test;
CREATE TRIGGER tg_inttest
BEFORE DELETE OR UPDATE OR INSERT ON delete_fdw_trigger_test
FOR EACH ROW EXECUTE PROCEDURE f_tg_test_broken();
-- should fail
SAVEPOINT broken;
INSERT INTO delete_fdw_trigger_test VALUES(1), (2), (3);
ROLLBACK TO broken;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
(0 rows)

-- should delete nothing
DELETE FROM delete_fdw_trigger_test WHERE id = 2;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
(0 rows)

-- should update nothing
UPDATE delete_fdw_trigger_test SET id = 4 WHERE id = 3;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
(0 rows)

DELETE FROM delete_fdw_trigger_test;
SELECT * FROM inttest;
f1 | f2 | f3
----+----+----
(0 rows)

DROP TRIGGER tg_inttest ON delete_fdw_trigger_test;
COMMIT;
--------------------------------------------------------------------------------
-- Regression Tests End, Cleanup
--------------------------------------------------------------------------------
DROP FOREIGN TABLE float_test;
Expand Down
10 changes: 9 additions & 1 deletion ifx_conncache.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@
*/
#define IFX_CONNCACHE_HASHTABLE "IFX_CONN_CACHE"

/*
* Flags for dynahash hashtable, version dependent
*/
#if PG_VERSION_NUM >= 140000
#define IFX_FDW_CONNCACHE_HASH_FLAGS HASH_ELEM | HASH_CONTEXT | HASH_STRINGS
#else
#define IFX_FDW_CONNCACHE_HASH_FLAGS HASH_ELEM | HASH_CONTEXT
#endif
static void ifxConnCache_init(void);

bool IfxCacheIsInitialized;
Expand Down Expand Up @@ -64,7 +72,7 @@ static void ifxConnCache_init()
ifxCache.connections = hash_create(IFX_CONNCACHE_HASHTABLE,
IFX_CONNCACHE_SIZE,
&hash_ctl,
HASH_ELEM | HASH_CONTEXT);
IFX_FDW_CONNCACHE_HASH_FLAGS);

/*
* Back to old context.
Expand Down
Loading

0 comments on commit b518b08

Please sign in to comment.