From a9e43b46afc53c31d10be591366b3ba811c223db Mon Sep 17 00:00:00 2001 From: balmeida Date: Thu, 11 Aug 2016 17:01:57 +0100 Subject: [PATCH] Add basic support for foreign tables --- README.md | 1 + .../startnet/utils/pgdiff/PgDiffTables.java | 6 +-- .../utils/pgdiff/loader/PgDumpLoader.java | 4 +- .../pgdiff/parsers/AlterRelationParser.java | 2 + .../pgdiff/parsers/CreateTableParser.java | 8 +++- .../startnet/utils/pgdiff/schema/PgTable.java | 40 ++++++++++++++++++- .../cz/startnet/utils/pgdiff/PgDiffTest.java | 7 ++++ .../utils/pgdiff/foreign_alter_type_diff.sql | 4 ++ .../utils/pgdiff/foreign_alter_type_new.sql | 17 ++++++++ .../pgdiff/foreign_alter_type_original.sql | 16 ++++++++ .../pgdiff/foreign_create_table_diff.sql | 7 ++++ .../utils/pgdiff/foreign_create_table_new.sql | 7 ++++ .../pgdiff/foreign_create_table_original.sql | 0 .../utils/pgdiff/foreign_drop_table_diff.sql | 2 + .../utils/pgdiff/foreign_drop_table_new.sql | 0 .../pgdiff/foreign_drop_table_original.sql | 7 ++++ 16 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_diff.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_new.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_original.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_diff.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_new.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_original.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_diff.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_new.sql create mode 100644 src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_original.sql diff --git a/README.md b/README.md index ecc04280..77b764de 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ fordfrog@fordfrog.com. * Add support for ALTER TABLE ... OWNER TO (serge-pouliquen-itf) * Add support for CREATE TYPE (Karol Rybak) * Add support for CREATE EXTENSION (Átila Camurça Alves) +* Add basic support for CREATE FOREIGN TABLE (Bruno Almeida) #### Fixes * Added hint to use "CREATE TABLE ... CONSTRAINT name PRIMARY KEY/UNIQUE ..." diff --git a/src/main/java/cz/startnet/utils/pgdiff/PgDiffTables.java b/src/main/java/cz/startnet/utils/pgdiff/PgDiffTables.java index a222e4c4..36e652d3 100644 --- a/src/main/java/cz/startnet/utils/pgdiff/PgDiffTables.java +++ b/src/main/java/cz/startnet/utils/pgdiff/PgDiffTables.java @@ -623,7 +623,7 @@ private static void updateTableColumns(final PrintWriter writer, PgDiffUtils.getQuotedName(newTable.getName()); searchPathHelper.outputSearchPath(writer); writer.println(); - writer.println("ALTER TABLE " + quotedTableName); + writer.println("ALTER " + ((newTable.isForeign()) ? "FOREIGN ":"") + "TABLE " + quotedTableName); for (int i = 0; i < statements.size(); i++) { writer.print(statements.get(i)); @@ -632,7 +632,7 @@ private static void updateTableColumns(final PrintWriter writer, if (!dropDefaultsColumns.isEmpty()) { writer.println(); - writer.println("ALTER TABLE " + quotedTableName); + writer.println("ALTER " + ((newTable.isForeign()) ? "FOREIGN ":"") + "TABLE " + quotedTableName); for (int i = 0; i < dropDefaultsColumns.size(); i++) { writer.print("\tALTER COLUMN "); @@ -865,7 +865,7 @@ private static void alterOwnerTo(final PrintWriter writer, if (newOwnerTo != null && !newOwnerTo.equals(oldOwnerTo)) { writer.println(); - writer.println("ALTER TABLE " + writer.println("ALTER " + ((newTable.isForeign()) ? "FOREIGN ":"") + "TABLE " + PgDiffUtils.getQuotedName(newTable.getName()) + " OWNER TO " + newTable.getOwnerTo() + ";"); } diff --git a/src/main/java/cz/startnet/utils/pgdiff/loader/PgDumpLoader.java b/src/main/java/cz/startnet/utils/pgdiff/loader/PgDumpLoader.java index ff8987a1..8aa9f766 100644 --- a/src/main/java/cz/startnet/utils/pgdiff/loader/PgDumpLoader.java +++ b/src/main/java/cz/startnet/utils/pgdiff/loader/PgDumpLoader.java @@ -54,7 +54,7 @@ public class PgDumpLoader { //NOPMD * Pattern for testing whether it is CREATE TABLE statement. */ private static final Pattern PATTERN_CREATE_TABLE = Pattern.compile( - "^CREATE[\\s]+(UNLOGGED\\s)*TABLE[\\s]+.*$", + "^CREATE[\\s]+(UNLOGGED\\s|FOREIGN\\s)*TABLE[\\s]+.*$", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); /** * Pattern for testing whether it is CREATE VIEW or CREATE MATERIALIZED @@ -67,7 +67,7 @@ public class PgDumpLoader { //NOPMD * Pattern for testing whether it is ALTER TABLE statement. */ private static final Pattern PATTERN_ALTER_TABLE = - Pattern.compile("^ALTER[\\s]+TABLE[\\s]+.*$", + Pattern.compile("^ALTER[\\s](FOREIGN)*TABLE[\\s]+.*$", Pattern.CASE_INSENSITIVE | Pattern.DOTALL); /** * Pattern for testing whether it is CREATE SEQUENCE statement. diff --git a/src/main/java/cz/startnet/utils/pgdiff/parsers/AlterRelationParser.java b/src/main/java/cz/startnet/utils/pgdiff/parsers/AlterRelationParser.java index 679cd022..47059fc3 100644 --- a/src/main/java/cz/startnet/utils/pgdiff/parsers/AlterRelationParser.java +++ b/src/main/java/cz/startnet/utils/pgdiff/parsers/AlterRelationParser.java @@ -37,6 +37,8 @@ public static void parse(final PgDatabase database, * relation types, so we just ignore type here and derive its type from * the original CREATE command. */ + parser.expectOptional("FOREIGN"); + //OK FOREIGN TABLE if (parser.expectOptional("TABLE")) { parser.expectOptional("ONLY"); } else if (parser.expectOptional("MATERIALIZED", "VIEW") diff --git a/src/main/java/cz/startnet/utils/pgdiff/parsers/CreateTableParser.java b/src/main/java/cz/startnet/utils/pgdiff/parsers/CreateTableParser.java index 73174447..3d4317d4 100644 --- a/src/main/java/cz/startnet/utils/pgdiff/parsers/CreateTableParser.java +++ b/src/main/java/cz/startnet/utils/pgdiff/parsers/CreateTableParser.java @@ -31,6 +31,7 @@ public static void parse(final PgDatabase database, final Parser parser = new Parser(statement); parser.expect("CREATE"); final boolean unlogged = parser.expectOptional("UNLOGGED"); + final boolean foreign = parser.expectOptional("FOREIGN"); parser.expect("TABLE"); // Optional IF NOT EXISTS, irrelevant for our purposes @@ -49,6 +50,7 @@ public static void parse(final PgDatabase database, final PgTable table = new PgTable(ParserUtils.getObjectName(tableName), database, schema); table.setUnlogged(unlogged); + table.setForeign(foreign); schema.addRelation(table); parser.expect("("); @@ -77,7 +79,7 @@ public static void parse(final PgDatabase database, if (parser.expectOptional("INHERITS")) { parseInherits(database, parser, table); } else if (parser.expectOptional("WITHOUT")) { - table.setWith("OIDS=false"); + table.setWith("OIDS=false"); } else if (parser.expectOptional("WITH")) { if (parser.expectOptional("OIDS") || parser.expectOptional("OIDS=true")) { @@ -89,8 +91,10 @@ public static void parse(final PgDatabase database, } } else if (parser.expectOptional("TABLESPACE")) { table.setTablespace(parser.parseString()); + } else if (parser.expectOptional("SERVER")) { + table.setForeignServer(parser.getExpression()); } else { - parser.throwUnsupportedCommand(); + parser.throwUnsupportedCommand(); } } } diff --git a/src/main/java/cz/startnet/utils/pgdiff/schema/PgTable.java b/src/main/java/cz/startnet/utils/pgdiff/schema/PgTable.java index 863f8a6a..93778e48 100644 --- a/src/main/java/cz/startnet/utils/pgdiff/schema/PgTable.java +++ b/src/main/java/cz/startnet/utils/pgdiff/schema/PgTable.java @@ -43,7 +43,11 @@ public class PgTable extends PgRelation { * Is this a UNLOGGED table? */ private boolean unlogged; - + /** + * Is this a FOREIGN table? + */ + private boolean foreign; + private String foreignServer; /** * PgDatabase @@ -114,6 +118,9 @@ public String getCreationSQL(final PgSchema schema) { if (isUnlogged()) { sbSQL.append("UNLOGGED "); } + if (isForeign()) { + sbSQL.append("FOREIGN "); + } sbSQL.append("TABLE "); sbSQL.append(PgDiffUtils.getQuotedName(name)); sbSQL.append(" ("); @@ -181,6 +188,11 @@ public String getCreationSQL(final PgSchema schema) { } } + if (isForeign()) { + sbSQL.append("SERVER "); + sbSQL.append(getForeignServer()); + } + if (tablespace != null && !tablespace.isEmpty()) { sbSQL.append(System.getProperty("line.separator")); sbSQL.append("TABLESPACE "); @@ -401,4 +413,30 @@ public boolean isUnlogged() { public void setUnlogged(boolean unlogged) { this.unlogged = unlogged; } + + /** + * Foreign Tables + */ + + @Override + public String getDropSQL() { + return "DROP " + ((isForeign()) ? "FOREIGN ":"") + getRelationKind() + " " + + PgDiffUtils.getQuotedName(getName()) + ";"; + } + + public boolean isForeign() { + return foreign; + } + + public void setForeign(boolean foreign) { + this.foreign = foreign; + } + + public void setForeignServer(String server){ + foreignServer = server; + } + + public String getForeignServer(){ + return foreignServer; + } } diff --git a/src/test/java/cz/startnet/utils/pgdiff/PgDiffTest.java b/src/test/java/cz/startnet/utils/pgdiff/PgDiffTest.java index ad9b12dd..fc98edbb 100644 --- a/src/test/java/cz/startnet/utils/pgdiff/PgDiffTest.java +++ b/src/test/java/cz/startnet/utils/pgdiff/PgDiffTest.java @@ -233,8 +233,10 @@ public static Collection parameters() { {"add_table_issue115", false, false, false, false}, {"add_column_issue134", false, false, false, false}, {"add_column_issue188", false, false, false, false}, + {"add_column_issue188", false, false, false, false}, {"view_alias_with_quote", false, false, false, false}, // Tests view triggers (support for 'INSTEAD OF') + //90 {"view_triggers", false, false, false, false}, // Tests privileges {"grant_on_table_sequence", false, false, false, false}, @@ -245,6 +247,11 @@ public static Collection parameters() { , {"add_type", false, false, false, false} , {"drop_type", false, false, false, false} , {"alter_type", false, false, false, false} + // Test Foreign Tables + , {"foreign_create_table", false, false, false, false} + , {"foreign_drop_table", false, false, false, false} + //100 + , {"foreign_alter_type", false, false, false, false} }); } /** diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_diff.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_diff.sql new file mode 100644 index 00000000..af81f28f --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_diff.sql @@ -0,0 +1,4 @@ +ALTER FOREIGN TABLE foreign_to_alter + ADD COLUMN country_code character varying(5), + ALTER COLUMN ref2 TYPE character varying(20) /* TYPE change - table: foreign_to_alter original: character varying(60) new: character varying(20) */, + ALTER COLUMN deleted TYPE numeric(1,0) /* TYPE change - table: foreign_to_alter original: boolean new: numeric(1,0) */; \ No newline at end of file diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_new.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_new.sql new file mode 100644 index 00000000..1e63f19d --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_new.sql @@ -0,0 +1,17 @@ +CREATE FOREIGN TABLE foreign_to_alter ( + id bigint, + user_id bigint, + ref1 character varying(60), + ref2 character varying(20), + inplay_stake_coef numeric, + pre_match_stake_coef numeric, + punter_limits character varying, + name character varying(60), + colour_cat character varying(30), + deleted numeric(1,0), + country_code character varying(5) +) +SERVER ats +OPTIONS ( + updatable 'false' +); \ No newline at end of file diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_original.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_original.sql new file mode 100644 index 00000000..dae6bc84 --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_alter_type_original.sql @@ -0,0 +1,16 @@ +CREATE FOREIGN TABLE foreign_to_alter ( + id bigint, + user_id bigint, + ref1 character varying(60), + ref2 character varying(60), + inplay_stake_coef numeric, + pre_match_stake_coef numeric, + punter_limits character varying, + name character varying(60), + colour_cat character varying(30), + deleted boolean +) +SERVER ats +OPTIONS ( + updatable 'false' +); \ No newline at end of file diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_diff.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_diff.sql new file mode 100644 index 00000000..02f59329 --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_diff.sql @@ -0,0 +1,7 @@ + +CREATE FOREIGN TABLE foreign_to_create ( + id bigint +)SERVER ats +OPTIONS ( + updatable 'false' +); diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_new.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_new.sql new file mode 100644 index 00000000..d0ea5c83 --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_new.sql @@ -0,0 +1,7 @@ + +CREATE FOREIGN TABLE foreign_to_create ( + id bigint +) SERVER ats +OPTIONS ( + updatable 'false' +); diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_original.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_create_table_original.sql new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_diff.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_diff.sql new file mode 100644 index 00000000..c858fcf0 --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_diff.sql @@ -0,0 +1,2 @@ + +DROP FOREIGN TABLE foreign_to_drop; diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_new.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_new.sql new file mode 100644 index 00000000..e69de29b diff --git a/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_original.sql b/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_original.sql new file mode 100644 index 00000000..90908c17 --- /dev/null +++ b/src/test/resources/cz/startnet/utils/pgdiff/foreign_drop_table_original.sql @@ -0,0 +1,7 @@ +CREATE FOREIGN TABLE foreign_to_drop ( + id bigint +) +SERVER ats +OPTIONS ( + updatable 'false' +); \ No newline at end of file