Skip to content

Commit

Permalink
Proper support for upper case table names
Browse files Browse the repository at this point in the history
Merge pull request #21 from nearform/yktv4-camel-case-support
  • Loading branch information
paolochiodi authored Jul 16, 2020
2 parents 79b68a9 + 6ba58c7 commit c4f4f42
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 17 deletions.
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@

# 0.4.0 - 2020/7/14

- Breaking change: the versioning function is not quoting and escaping the name of the history table. Any name that needs quoting (upper case, special chars) should be provided as parameters already quoted and escaped.

# 0.3.0 - 2020/7/14

- Add parameter to ignore updates without actual changes
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# Temporal Tables

_Version: 0.3.0_
_Version: 0.4.0_

This is an attempt to rewrite the postgresql [temporal_tables](https://github.com/arkhipov/temporal_tables) extension in PL/pgSQL, without the need for external c extension.

Expand Down Expand Up @@ -66,6 +66,11 @@ FOR EACH ROW EXECUTE PROCEDURE versioning(
);
```

A note on the history table name. Previous versions of this extension quoted and escaped it before usage.
Starting version 0.4.0 we are not escaping it anymore and users need to provide the escaped version as a parameter to the trigger.

This is consistent with the c version, simplifies the extension code and fixes an issue with upper case names that weren't properly supported.

Now test with some data:

```sql
Expand Down
153 changes: 153 additions & 0 deletions test/expected/upper_case.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
CREATE TABLE "Versioning" (a bigint, "b b" date, sys_period tstzrange);
-- Insert some data before versioning is enabled.
INSERT INTO "Versioning" (a, sys_period) VALUES (1, tstzrange('-infinity', NULL));
INSERT INTO "Versioning" (a, sys_period) VALUES (2, tstzrange('2000-01-01', NULL));
CREATE TABLE "VersioningHistory" (a bigint, c date, sys_period tstzrange);
CREATE TRIGGER "VersioningTrigger"
BEFORE INSERT OR UPDATE OR DELETE ON "Versioning"
FOR EACH ROW EXECUTE PROCEDURE versioning('sys_period', '"VersioningHistory"', false);
-- Insert.
BEGIN;
INSERT INTO "Versioning" (a) VALUES (3);
SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;
a | b b | ?column?
---+-----+----------
1 | | f
2 | | f
3 | | t
(3 rows)

SELECT * FROM "VersioningHistory" ORDER BY a, sys_period;
a | c | sys_period
---+---+------------
(0 rows)

COMMIT;
-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);
pg_sleep
----------

(1 row)

-- Update.
BEGIN;
UPDATE "Versioning" SET a = 4 WHERE a = 3;
SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;
a | b b | ?column?
---+-----+----------
1 | | f
2 | | f
4 | | t
(3 rows)

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;
a | c | ?column?
---+---+----------
3 | | t
(1 row)

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;
a | b b
---+-----
4 |
(1 row)

COMMIT;
-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);
pg_sleep
----------

(1 row)

-- Multiple updates.
BEGIN;
UPDATE "Versioning" SET a = 5 WHERE a = 4;
UPDATE "Versioning" SET "b b" = '2012-01-01' WHERE a = 5;
SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;
a | b b | ?column?
---+------------+----------
1 | | f
2 | | f
5 | 2012-01-01 | t
(3 rows)

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;
a | c | ?column?
---+---+----------
3 | | f
4 | | t
(2 rows)

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;
a | b b
---+------------
5 | 2012-01-01
(1 row)

COMMIT;
-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);
pg_sleep
----------

(1 row)

-- Delete.
BEGIN;
DELETE FROM "Versioning" WHERE a = 4;
SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;
a | b b | ?column?
---+------------+----------
1 | | f
2 | | f
5 | 2012-01-01 | f
(3 rows)

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;
a | c | ?column?
---+---+----------
3 | | f
4 | | f
(2 rows)

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;
a | b b
---+-----
(0 rows)

END;
-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);
pg_sleep
----------

(1 row)

-- Delete.
BEGIN;
DELETE FROM "Versioning";
SELECT * FROM "Versioning";
a | b b | sys_period
---+-----+------------
(0 rows)

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;
a | c | ?column?
---+---+----------
1 | | t
2 | | t
3 | | f
4 | | f
5 | | t
(5 rows)

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;
a | b b
---+-----
(0 rows)

END;
DROP TABLE "Versioning";
DROP TABLE "VersioningHistory";
3 changes: 2 additions & 1 deletion test/runTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ mkdir -p test/result
TESTS="
no_history_table no_history_system_period no_system_period
invalid_system_period_values invalid_system_period invalid_types
versioning structure combinations different_schema unchanged_values"
versioning upper_case structure combinations
different_schema unchanged_values"

for name in $TESTS; do
echo ""
Expand Down
2 changes: 1 addition & 1 deletion test/runTestNochecks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ psql temporal_tables_test -q -f versioning_function_nochecks.sql

mkdir -p test/result

TESTS="versioning structure combinations different_schema unchanged_values"
TESTS="versioning upper_case structure combinations different_schema unchanged_values"

for name in $TESTS; do
echo ""
Expand Down
90 changes: 90 additions & 0 deletions test/sql/upper_case.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
CREATE TABLE "Versioning" (a bigint, "b b" date, sys_period tstzrange);

-- Insert some data before versioning is enabled.
INSERT INTO "Versioning" (a, sys_period) VALUES (1, tstzrange('-infinity', NULL));
INSERT INTO "Versioning" (a, sys_period) VALUES (2, tstzrange('2000-01-01', NULL));

CREATE TABLE "VersioningHistory" (a bigint, c date, sys_period tstzrange);

CREATE TRIGGER "VersioningTrigger"
BEFORE INSERT OR UPDATE OR DELETE ON "Versioning"
FOR EACH ROW EXECUTE PROCEDURE versioning('sys_period', '"VersioningHistory"', false);

-- Insert.
BEGIN;

INSERT INTO "Versioning" (a) VALUES (3);

SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;

SELECT * FROM "VersioningHistory" ORDER BY a, sys_period;

COMMIT;

-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);

-- Update.
BEGIN;

UPDATE "Versioning" SET a = 4 WHERE a = 3;

SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;

COMMIT;

-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);

-- Multiple updates.
BEGIN;

UPDATE "Versioning" SET a = 5 WHERE a = 4;
UPDATE "Versioning" SET "b b" = '2012-01-01' WHERE a = 5;

SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;

COMMIT;

-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);

-- Delete.
BEGIN;

DELETE FROM "Versioning" WHERE a = 4;

SELECT a, "b b", lower(sys_period) = CURRENT_TIMESTAMP FROM "Versioning" ORDER BY a, sys_period;

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;

END;

-- Make sure that the next transaction's CURRENT_TIMESTAMP is different.
SELECT pg_sleep(0.1);

-- Delete.
BEGIN;

DELETE FROM "Versioning";

SELECT * FROM "Versioning";

SELECT a, c, upper(sys_period) = CURRENT_TIMESTAMP FROM "VersioningHistory" ORDER BY a, sys_period;

SELECT a, "b b" FROM "Versioning" WHERE lower(sys_period) = CURRENT_TIMESTAMP ORDER BY a, sys_period;

END;

DROP TABLE "Versioning";
DROP TABLE "VersioningHistory";
9 changes: 2 additions & 7 deletions versioning_function.sql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ DECLARE
holder2 record;
pg_version integer;
BEGIN
-- version 0.3.0
-- version 0.4.0

IF TG_WHEN != 'BEFORE' OR TG_LEVEL != 'ROW' THEN
RAISE TRIGGER_PROTOCOL_VIOLATED USING
Expand Down Expand Up @@ -165,12 +165,7 @@ BEGIN
AND history.attname != sys_period;

EXECUTE ('INSERT INTO ' ||
CASE split_part(history_table, '.', 2)
WHEN '' THEN
quote_ident(history_table)
ELSE
quote_ident(split_part(history_table, '.', 1)) || '.' || quote_ident(split_part(history_table, '.', 2))
END ||
history_table ||
'(' ||
array_to_string(commonColumns , ',') ||
',' ||
Expand Down
9 changes: 2 additions & 7 deletions versioning_function_nochecks.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ DECLARE
transaction_info txid_snapshot;
existing_range tstzrange;
BEGIN
-- version 0.3.0
-- version 0.4.0

sys_period := TG_ARGV[0];
history_table := TG_ARGV[1];
Expand Down Expand Up @@ -62,12 +62,7 @@ BEGIN
AND history.attname != sys_period;

EXECUTE ('INSERT INTO ' ||
CASE split_part(history_table, '.', 2)
WHEN '' THEN
quote_ident(history_table)
ELSE
quote_ident(split_part(history_table, '.', 1)) || '.' || quote_ident(split_part(history_table, '.', 2))
END ||
history_table ||
'(' ||
array_to_string(commonColumns , ',') ||
',' ||
Expand Down

0 comments on commit c4f4f42

Please sign in to comment.