From d9d4f99d29ee37c29311102e7a2b0fad3381e9fe Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Wed, 4 May 2016 21:08:06 +0300 Subject: [PATCH 1/8] Add postgresql 9.6 compatibility --- Makefile | 4 ++-- cstore_fdw.c | 22 +++++++++++++++++++++- cstore_fdw.h | 1 + 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index c47e37d..09e93b2 100644 --- a/Makefile +++ b/Makefile @@ -40,8 +40,8 @@ ifndef MAJORVERSION MAJORVERSION := $(basename $(VERSION)) endif -ifeq (,$(findstring $(MAJORVERSION), 9.3 9.4 9.5)) - $(error PostgreSQL 9.3 or 9.4 or 9.5 is required to compile this extension) +ifeq (,$(findstring $(MAJORVERSION), 9.3 9.4 9.5 9.6)) + $(error PostgreSQL 9.3 or 9.4 or 9.5 or 9.6 is required to compile this extension) endif cstore.pb-c.c: cstore.proto diff --git a/cstore_fdw.c b/cstore_fdw.c index 1af09f2..037c779 100644 --- a/cstore_fdw.c +++ b/cstore_fdw.c @@ -1296,7 +1296,17 @@ CStoreGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid foreignTableId double totalCost = startupCost + totalCpuCost + totalDiskAccessCost; /* create a foreign path node and add it as the only possible path */ -#if PG_VERSION_NUM >= 90500 +#if PG_VERSION_NUM >= 90600 + foreignScanPath = (Path *) create_foreignscan_path(root, baserel, + NULL, /* path target */ + baserel->rows, + startupCost, totalCost, + NIL, /* no known ordering */ + NULL, /* not parameterized */ + NULL, /* no outer path */ + NIL); /* no fdw_private */ + +#elif PG_VERSION_NUM >= 90500 foreignScanPath = (Path *) create_foreignscan_path(root, baserel, baserel->rows, startupCost, totalCost, NIL, /* no known ordering */ @@ -1440,7 +1450,11 @@ ColumnList(RelOptInfo *baserel, Oid foreignTableId) List *neededColumnList = NIL; AttrNumber columnIndex = 1; AttrNumber columnCount = baserel->max_attr; +#if PG_VERSION_NUM >= 90600 + List *targetColumnList = baserel->reltarget->exprs; +#else List *targetColumnList = baserel->reltargetlist; +#endif List *restrictInfoList = baserel->baserestrictinfo; ListCell *restrictInfoCell = NULL; const AttrNumber wholeRow = 0; @@ -1459,9 +1473,15 @@ ColumnList(RelOptInfo *baserel, Oid foreignTableId) List *clauseColumnList = NIL; /* recursively pull up any columns used in the restriction clause */ +#if PG_VERSION_NUM >= 90600 + clauseColumnList = pull_var_clause(restrictClause, + PVC_RECURSE_AGGREGATES | + PVC_RECURSE_PLACEHOLDERS); +#else clauseColumnList = pull_var_clause(restrictClause, PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS); +#endif neededColumnList = list_union(neededColumnList, clauseColumnList); } diff --git a/cstore_fdw.h b/cstore_fdw.h index e126ffb..c0aa9c1 100644 --- a/cstore_fdw.h +++ b/cstore_fdw.h @@ -16,6 +16,7 @@ #include "access/tupdesc.h" #include "fmgr.h" +#include "catalog/pg_am.h" #include "catalog/pg_foreign_server.h" #include "catalog/pg_foreign_table.h" #include "lib/stringinfo.h" From a02b7ee4ef35eb6585d8736e13e331f4b964d253 Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Mon, 25 Jul 2016 17:20:26 +0300 Subject: [PATCH 2/8] Remove unused code --- cstore_writer.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/cstore_writer.c b/cstore_writer.c index dbc348b..2753c29 100644 --- a/cstore_writer.c +++ b/cstore_writer.c @@ -422,23 +422,14 @@ CreateEmptyStripeBuffers(uint32 stripeMaxRowCount, uint32 blockRowCount, StripeBuffers *stripeBuffers = NULL; uint32 columnIndex = 0; uint32 maxBlockCount = (stripeMaxRowCount / blockRowCount) + 1; - ColumnBuffers **columnBuffersArray = palloc0(columnCount * sizeof(ColumnBuffers *)); - ColumnBlockData **blockDataArray = palloc0(columnCount * sizeof(ColumnBlockData*)); for (columnIndex = 0; columnIndex < columnCount; columnIndex++) { uint32 blockIndex = 0; - ColumnBlockBuffers **blockBuffersArray = NULL; - ColumnBlockData *blockData = palloc0(sizeof(ColumnBlockData)); - bool *existsArray = palloc0(blockRowCount * sizeof(bool)); - Datum *valueArray = palloc0(blockRowCount * sizeof(Datum)); - - blockData->existsArray = existsArray; - blockData->valueArray = valueArray; - blockData->valueBuffer = NULL; - blockDataArray[columnIndex] = blockData; - blockBuffersArray = palloc0(maxBlockCount * sizeof(ColumnBlockBuffers *)); + ColumnBlockBuffers **blockBuffersArray = + palloc0(maxBlockCount * sizeof(ColumnBlockBuffers *)); + for (blockIndex = 0; blockIndex < maxBlockCount; blockIndex++) { blockBuffersArray[blockIndex] = palloc0(sizeof(ColumnBlockBuffers)); From c89fcbed37733f92745a15206cda94724bae3a3b Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Thu, 28 Jul 2016 17:09:31 +0300 Subject: [PATCH 3/8] Add alter column type verifications to prevent incorrect changes --- cstore_fdw.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ expected/alter.out | 12 ++++++++ sql/alter.sql | 15 ++++++++++ 3 files changed, 99 insertions(+) diff --git a/cstore_fdw.c b/cstore_fdw.c index 037c779..7520a18 100644 --- a/cstore_fdw.c +++ b/cstore_fdw.c @@ -44,6 +44,8 @@ #include "optimizer/var.h" #include "parser/parser.h" #include "parser/parsetree.h" +#include "parser/parse_coerce.h" +#include "parser/parse_type.h" #include "tcop/utility.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -69,6 +71,7 @@ static void CStoreProcessCopyCommand(CopyStmt *copyStatement, const char *queryS static uint64 CopyIntoCStoreTable(const CopyStmt *copyStatement, const char *queryString); static uint64 CopyOutCStoreTable(CopyStmt* copyStatement, const char* queryString); +static void CStoreProcessAlterTableCommand(AlterTableStmt *alterStatement); static List * DroppedCStoreFilenameList(DropStmt *dropStatement); static List * FindCStoreTables(List *tableList); static void TruncateCStoreTables(List *cstoreTableList); @@ -266,6 +269,13 @@ CStoreProcessUtility(Node *parseTree, const char *queryString, TruncateCStoreTables(cstoreTablesList); } + else if (nodeTag(parseTree) == T_AlterTableStmt) + { + AlterTableStmt *alterTable = (AlterTableStmt *) parseTree; + CStoreProcessAlterTableCommand(alterTable); + CallPreviousProcessUtility(parseTree, queryString, context, + paramListInfo, destReceiver, completionTag); + } /* handle other utility statements */ else { @@ -530,6 +540,68 @@ CopyOutCStoreTable(CopyStmt* copyStatement, const char* queryString) } +/* + * CStoreProcessAlterTableCommand checks if given alter table statement is + * compatible with underlying data structure. Currently it only checks alter + * column type. The function errors out if current column type can not be safely + * converted to requested column type. This check is more restrictive than + * PostgreSQL's because we can not change existing data. + */ +static void +CStoreProcessAlterTableCommand(AlterTableStmt *alterStatement) +{ + ObjectType objectType = alterStatement->relkind; + RangeVar *relationRangeVar = alterStatement->relation; + Oid relationId = InvalidOid; + List *commandList = alterStatement->cmds; + ListCell *commandCell = NULL; + + /* we are only interested in foreign table changes */ + if (objectType != OBJECT_TABLE && objectType != OBJECT_FOREIGN_TABLE) + { + return; + } + + relationId = RangeVarGetRelid(relationRangeVar, AccessShareLock, true); + if (!CStoreTable(relationId)) + { + return; + } + + foreach(commandCell, commandList) + { + AlterTableCmd *alterCommand = (AlterTableCmd *) lfirst(commandCell); + if(alterCommand->subtype == AT_AlterColumnType) + { + char *columnName = alterCommand->name; + ColumnDef *columnDef = (ColumnDef *) alterCommand->def; + Oid targetTypeId = typenameTypeId(NULL, columnDef->typeName);; + char *typeName = TypeNameToString(columnDef->typeName); + AttrNumber attributeNumber = get_attnum(relationId, columnName); + Oid currentTypeId = InvalidOid; + + if (attributeNumber <= 0) + { + /* let standard utility handle this */ + continue; + } + + currentTypeId = get_atttype(relationId, attributeNumber); + + /* + * We are only interested in implicit coersion type compatibility. + * Erroring out here to prevent further processing. + */ + if (!can_coerce_type(1, ¤tTypeId, &targetTypeId, COERCION_IMPLICIT)) + { + ereport(ERROR, (errmsg("Column %s cannot be cast automatically to " + "type %s", columnName, typeName))); + } + } + } +} + + /* * DropppedCStoreFilenameList extracts and returns the list of cstore file names * from DROP table statement diff --git a/expected/alter.out b/expected/alter.out index 2ca3e54..548fb9e 100644 --- a/expected/alter.out +++ b/expected/alter.out @@ -151,4 +151,16 @@ SELECT * FROM test_alter_table; 1 | 4 | ABCDEF | | (7 rows) +-- unsupported type change +ALTER FOREIGN TABLE test_alter_table ADD COLUMN i int; +ALTER FOREIGN TABLE test_alter_table ADD COLUMN j float; +ALTER FOREIGN TABLE test_alter_table ADD COLUMN k text; +-- this is valid type change +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN i TYPE float; +-- this is not valid +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN j TYPE int; +ERROR: Column j cannot be cast automatically to type pg_catalog.int4 +-- text / varchar conversion is valid both ways +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN k TYPE varchar(20); +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN k TYPE text; DROP FOREIGN TABLE test_alter_table; diff --git a/sql/alter.sql b/sql/alter.sql index eb21056..f03e58c 100644 --- a/sql/alter.sql +++ b/sql/alter.sql @@ -65,4 +65,19 @@ ALTER FOREIGN TABLE test_alter_table ALTER COLUMN h DROP DEFAULT; ANALYZE test_alter_table; SELECT * FROM test_alter_table; +-- unsupported type change +ALTER FOREIGN TABLE test_alter_table ADD COLUMN i int; +ALTER FOREIGN TABLE test_alter_table ADD COLUMN j float; +ALTER FOREIGN TABLE test_alter_table ADD COLUMN k text; + +-- this is valid type change +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN i TYPE float; + +-- this is not valid +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN j TYPE int; + +-- text / varchar conversion is valid both ways +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN k TYPE varchar(20); +ALTER FOREIGN TABLE test_alter_table ALTER COLUMN k TYPE text; + DROP FOREIGN TABLE test_alter_table; From 531f2c4e8d51bfb810903ce54969e3e5654c295b Mon Sep 17 00:00:00 2001 From: Jason Petersen Date: Tue, 2 Aug 2016 21:23:44 -0700 Subject: [PATCH 4/8] Lock tools version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a404e96..35e97c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ env: before_install: - sudo apt-get update -qq - sudo update-alternatives --remove-all postmaster.1.gz - - git clone --depth 1 https://github.com/citusdata/tools.git + - git clone -b v0.3.3 --depth 1 https://github.com/citusdata/tools.git - tools/travis/nuke_pg.sh install: - sudo apt-get install protobuf-c-compiler From f42f004b9a0cafcff71c2dd2082f5976551f8aac Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Wed, 10 Aug 2016 09:32:27 +0300 Subject: [PATCH 5/8] Ignore distributed tables in truncate handler --- cstore_fdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cstore_fdw.c b/cstore_fdw.c index 037c779..62b82ad 100644 --- a/cstore_fdw.c +++ b/cstore_fdw.c @@ -571,7 +571,7 @@ FindCStoreTables(List *tableList) { RangeVar *rangeVar = (RangeVar *) lfirst(relationCell); Oid relationId = RangeVarGetRelid(rangeVar, AccessShareLock, true); - if (CStoreTable(relationId)) + if (CStoreTable(relationId) && !DistributedTable(relationId)) { cstoreTableList = lappend(cstoreTableList, rangeVar); } From 3a192ff7f1ef0a92457a3f6e39b2830b86bed5e6 Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Mon, 25 Jul 2016 15:27:11 +0300 Subject: [PATCH 6/8] Reduce function calls to var's during requested column computation --- cstore_fdw.c | 22 ++++++++++++++++++++-- expected/query.out | 21 +++++++++++++++++++++ sql/query.sql | 11 +++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/cstore_fdw.c b/cstore_fdw.c index 7520a18..0c83a99 100644 --- a/cstore_fdw.c +++ b/cstore_fdw.c @@ -1513,7 +1513,8 @@ PageCount(const char *filename) * ColumnList takes in the planner's information about this foreign table. The * function then finds all columns needed for query execution, including those * used in projections, joins, and filter clauses, de-duplicates these columns, - * and returns them in a new list. This function is unchanged from mongo_fdw. + * and returns them in a new list. This function is taken from mongo_fdw with + * slight modifications. */ static List * ColumnList(RelOptInfo *baserel, Oid foreignTableId) @@ -1527,6 +1528,7 @@ ColumnList(RelOptInfo *baserel, Oid foreignTableId) #else List *targetColumnList = baserel->reltargetlist; #endif + ListCell *targetColumnCell = NULL; List *restrictInfoList = baserel->baserestrictinfo; ListCell *restrictInfoCell = NULL; const AttrNumber wholeRow = 0; @@ -1535,7 +1537,23 @@ ColumnList(RelOptInfo *baserel, Oid foreignTableId) Form_pg_attribute *attributeFormArray = tupleDescriptor->attrs; /* first add the columns used in joins and projections */ - neededColumnList = list_copy(targetColumnList); + foreach(targetColumnCell, targetColumnList) + { + List *targetVarList = NIL; + Node *targetExpr = (Node *) lfirst(targetColumnCell); + +#if PG_VERSION_NUM >= 90600 + targetVarList = pull_var_clause(targetExpr, + PVC_RECURSE_AGGREGATES | + PVC_RECURSE_PLACEHOLDERS); +#else + targetVarList = pull_var_clause(targetExpr, + PVC_RECURSE_AGGREGATES, + PVC_RECURSE_PLACEHOLDERS); +#endif + + neededColumnList = list_union(neededColumnList, targetVarList); + } /* then walk over all restriction clauses, and pull up any used columns */ foreach(restrictInfoCell, restrictInfoList) diff --git a/expected/query.out b/expected/query.out index d3811fc..7ac3508 100644 --- a/expected/query.out +++ b/expected/query.out @@ -82,3 +82,24 @@ SELECT to_json(v) FROM contestant v ORDER BY rating LIMIT 1; {"handle":"g","birthdate":"1991-12-13","rating":1803,"percentile":85.1,"country":"XD ","achievements":["a","c"]} (1 row) +-- Test variables used in expressions +CREATE FOREIGN TABLE union_first (a int, b int) SERVER cstore_server; +CREATE FOREIGN TABLE union_second (a int, b int) SERVER cstore_server; +INSERT INTO union_first SELECT a, a FROM generate_series(1, 5) a; +INSERT INTO union_second SELECT a, a FROM generate_series(11, 15) a; +(SELECT a*1, b FROM union_first) union all (SELECT a*1, b FROM union_second); + ?column? | b +----------+---- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 11 | 11 + 12 | 12 + 13 | 13 + 14 | 14 + 15 | 15 +(10 rows) + +DROP FOREIGN TABLE union_first, union_second; diff --git a/sql/query.sql b/sql/query.sql index c56ee15..87743e7 100644 --- a/sql/query.sql +++ b/sql/query.sql @@ -21,3 +21,14 @@ SELECT * FROM contestant_compressed ORDER BY handle; -- Verify that we handle whole-row references correctly SELECT to_json(v) FROM contestant v ORDER BY rating LIMIT 1; + +-- Test variables used in expressions +CREATE FOREIGN TABLE union_first (a int, b int) SERVER cstore_server; +CREATE FOREIGN TABLE union_second (a int, b int) SERVER cstore_server; + +INSERT INTO union_first SELECT a, a FROM generate_series(1, 5) a; +INSERT INTO union_second SELECT a, a FROM generate_series(11, 15) a; + +(SELECT a*1, b FROM union_first) union all (SELECT a*1, b FROM union_second); + +DROP FOREIGN TABLE union_first, union_second; From 96fc74bab03ce90b0a2360f00e8ac7f57094f14a Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Wed, 31 Aug 2016 17:01:01 +0300 Subject: [PATCH 7/8] Remove dropped cstore files via sql drop event --- cstore_fdw--1.4.sql | 27 ++++++++++++++++++++++++++ cstore_fdw.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ expected/drop.out | 5 +++++ sql/drop.sql | 5 +++++ 4 files changed, 83 insertions(+) diff --git a/cstore_fdw--1.4.sql b/cstore_fdw--1.4.sql index 7a0ce25..4f21e30 100644 --- a/cstore_fdw--1.4.sql +++ b/cstore_fdw--1.4.sql @@ -30,3 +30,30 @@ CREATE FUNCTION cstore_table_size(relation regclass) RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C STRICT; + +CREATE FUNCTION cstore_clean_table_resources(oid) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + +CREATE OR REPLACE FUNCTION cstore_drop_trigger() + RETURNS event_trigger + LANGUAGE plpgsql + AS $csdt$ +DECLARE v_obj record; +BEGIN + FOR v_obj IN SELECT * FROM pg_event_trigger_dropped_objects() LOOP + + IF v_obj.object_type NOT IN ('table', 'foreign table') THEN + CONTINUE; + END IF; + + PERFORM cstore_clean_table_resources(v_obj.objid); + + END LOOP; +END; +$csdt$; + +CREATE EVENT TRIGGER cstore_drop_event + ON SQL_DROP + EXECUTE PROCEDURE cstore_drop_trigger(); \ No newline at end of file diff --git a/cstore_fdw.c b/cstore_fdw.c index 403c68a..5c8b5c7 100644 --- a/cstore_fdw.c +++ b/cstore_fdw.c @@ -139,6 +139,7 @@ PG_FUNCTION_INFO_V1(cstore_ddl_event_end_trigger); PG_FUNCTION_INFO_V1(cstore_table_size); PG_FUNCTION_INFO_V1(cstore_fdw_handler); PG_FUNCTION_INFO_V1(cstore_fdw_validator); +PG_FUNCTION_INFO_V1(cstore_clean_table_resources); /* saved hook value in case of unload */ @@ -623,6 +624,18 @@ DroppedCStoreFilenameList(DropStmt *dropStatement) if (CStoreTable(relationId)) { CStoreFdwOptions *cstoreFdwOptions = CStoreGetOptions(relationId); + char *defaultfilename = CStoreDefaultFilePath(relationId); + + /* + * Skip files that are placed in default location, they are handled + * by sql drop trigger. Both paths are generated by code, use + * of strcmp is safe here. + */ + if (strcmp(defaultfilename, cstoreFdwOptions->filename) == 0) + { + continue; + } + droppedCStoreFileList = lappend(droppedCStoreFileList, cstoreFdwOptions->filename); } @@ -1072,6 +1085,39 @@ cstore_fdw_validator(PG_FUNCTION_ARGS) } +/* + * cstore_clean_table_resources cleans up table data and metadata with provided + * relation id. The function is meant to be called from drop_event_trigger. It + * has no way of knowing if the provided relation id belongs to a cstore table. + * Therefore it first checks if data file exists at default location before + * attempting to remove data and footer files. If the table is created at a + * custom path than its resources would not be removed. + */ +Datum +cstore_clean_table_resources(PG_FUNCTION_ARGS) +{ + Oid relationId = PG_GETARG_OID(0); + StringInfo filePath = makeStringInfo(); + struct stat fileStat; + int statResult = -1; + + appendStringInfo(filePath, "%s/%s/%d/%d", DataDir, CSTORE_FDW_NAME, + (int) MyDatabaseId, (int) relationId); + + /* + * Check to see if the file exist first. This is the only way to + * find out if the table being dropped is a cstore table. + */ + statResult = stat(filePath->data, &fileStat); + if (statResult == 0) + { + DeleteCStoreTableFiles(filePath->data); + } + + PG_RETURN_VOID(); +} + + /* * OptionNamesString finds all options that are valid for the current context, * and concatenates these option names in a comma separated string. The function diff --git a/expected/drop.out b/expected/drop.out index 4cb594a..e065663 100644 --- a/expected/drop.out +++ b/expected/drop.out @@ -15,6 +15,11 @@ SELECT count(*) FROM ( -- DROP cstore_fdw tables DROP FOREIGN TABLE contestant; DROP FOREIGN TABLE contestant_compressed; +-- Create a cstore_fdw table under a schema and drop it. +CREATE SCHEMA test_schema; +CREATE FOREIGN TABLE test_schema.test_table(data int) SERVER cstore_server; +DROP SCHEMA test_schema CASCADE; +NOTICE: drop cascades to foreign table test_schema.test_table -- Check that the files have been deleted and the directory is empty after the -- DROP table command. SELECT count(*) FROM ( diff --git a/sql/drop.sql b/sql/drop.sql index d77115a..ff00980 100644 --- a/sql/drop.sql +++ b/sql/drop.sql @@ -13,6 +13,11 @@ SELECT count(*) FROM ( DROP FOREIGN TABLE contestant; DROP FOREIGN TABLE contestant_compressed; +-- Create a cstore_fdw table under a schema and drop it. +CREATE SCHEMA test_schema; +CREATE FOREIGN TABLE test_schema.test_table(data int) SERVER cstore_server; +DROP SCHEMA test_schema CASCADE; + -- Check that the files have been deleted and the directory is empty after the -- DROP table command. SELECT count(*) FROM ( From 932b8cf8357e9156256638caa331d2854d899104 Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Mon, 5 Sep 2016 14:42:08 +0300 Subject: [PATCH 8/8] Bump cstore version to 1.5 --- META.json | 6 ++--- Makefile | 4 ++-- README.md | 17 +++++++++---- cstore_fdw--1.4--1.5.sql | 28 ++++++++++++++++++++++ cstore_fdw--1.4.sql => cstore_fdw--1.5.sql | 4 ++-- cstore_fdw.control | 2 +- cstore_fdw.h | 2 +- 7 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 cstore_fdw--1.4--1.5.sql rename cstore_fdw--1.4.sql => cstore_fdw--1.5.sql (89%) diff --git a/META.json b/META.json index e19db25..abf048c 100644 --- a/META.json +++ b/META.json @@ -2,15 +2,15 @@ "name": "cstore_fdw", "abstract": "Columnar Store for PostgreSQL", "description": "PostgreSQL extension which implements a Columnar Store.", - "version": "1.4.1", + "version": "1.5.0", "maintainer": "Murat Tuncer ", "license": "apache_2_0", "provides": { "cstore_fdw": { "abstract": "Foreign Data Wrapper for Columnar Store Tables", - "file": "cstore_fdw--1.4.sql", + "file": "cstore_fdw--1.5.sql", "docfile": "README.md", - "version": "1.4.1" + "version": "1.5.0" } }, "prereqs": { diff --git a/Makefile b/Makefile index 09e93b2..30966fc 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,8 @@ OBJS = cstore.pb-c.o cstore_fdw.o cstore_writer.o cstore_reader.o \ cstore_metadata_serialization.o cstore_compression.o EXTENSION = cstore_fdw -DATA = cstore_fdw--1.4.sql cstore_fdw--1.3--1.4.sql cstore_fdw--1.2--1.3.sql \ - cstore_fdw--1.1--1.2.sql cstore_fdw--1.0--1.1.sql +DATA = cstore_fdw--1.5.sql cstore_fdw--1.4--1.5.sql cstore_fdw--1.3--1.4.sql \ + cstore_fdw--1.2--1.3.sql cstore_fdw--1.1--1.2.sql cstore_fdw--1.0--1.1.sql REGRESS = create load query analyze data_types functions block_filtering drop \ insert copyto alter truncate diff --git a/README.md b/README.md index 0dd66d7..0cb01f1 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,8 @@ installation's bin/ directory path. For example: PATH=/usr/local/pgsql/bin/:$PATH make sudo PATH=/usr/local/pgsql/bin/:$PATH make install -**Note.** cstore_fdw requires PostgreSQL 9.3, 9.4 or 9.5. It doesn't support earlier -versions of PostgreSQL. +**Note.** cstore_fdw requires PostgreSQL 9.3, 9.4, 9.5 or 9.6. It doesn't +support earlier versions of PostgreSQL. Usage @@ -115,13 +115,13 @@ most efficient execution plan for each query. commands. We also don't support single row inserts. -Updating from earlier versions to 1.4.1 +Updating from earlier versions to 1.5 --------------------------------------- -To update an existing cstore_fdw installation from versions earlier than 1.4.1 +To update an existing cstore_fdw installation from versions earlier than 1.5 you can take the following steps: -* Download and install cstore_fdw version 1.4.1 using instructions from the "Building" +* Download and install cstore_fdw version 1.5 using instructions from the "Building" section, * Restart the PostgreSQL server, * Run ```ALTER EXTENSION cstore_fdw UPDATE;``` @@ -284,6 +284,13 @@ the installation: Changeset --------- +### Version 1.5 +* (Feature) Added support for PostgresSQL 9.6. +* (Fix) Removed table data when cstore_fdw table is indirectly dropped. +* (Fix) Removed unused code fragments. +* (Fix) Fixed column selection logic to return columns used in expressions. +* (Fix) Prevented alter table command from changinf column type to incompatible types. + ### Version 1.4.1 * (Fix) Compatibility fix for Citus [copy command][copy-command]. diff --git a/cstore_fdw--1.4--1.5.sql b/cstore_fdw--1.4--1.5.sql new file mode 100644 index 0000000..4d7499b --- /dev/null +++ b/cstore_fdw--1.4--1.5.sql @@ -0,0 +1,28 @@ +/* cstore_fdw/cstore_fdw--1.4--1.5.sql */ + +CREATE FUNCTION cstore_clean_table_resources(oid) +RETURNS void +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT; + +CREATE OR REPLACE FUNCTION cstore_drop_trigger() + RETURNS event_trigger + LANGUAGE plpgsql + AS $csdt$ +DECLARE v_obj record; +BEGIN + FOR v_obj IN SELECT * FROM pg_event_trigger_dropped_objects() LOOP + + IF v_obj.object_type NOT IN ('table', 'foreign table') THEN + CONTINUE; + END IF; + + PERFORM cstore_clean_table_resources(v_obj.objid); + + END LOOP; +END; +$csdt$; + +CREATE EVENT TRIGGER cstore_drop_event + ON SQL_DROP + EXECUTE PROCEDURE cstore_drop_trigger(); \ No newline at end of file diff --git a/cstore_fdw--1.4.sql b/cstore_fdw--1.5.sql similarity index 89% rename from cstore_fdw--1.4.sql rename to cstore_fdw--1.5.sql index 4f21e30..0a886f8 100644 --- a/cstore_fdw--1.4.sql +++ b/cstore_fdw--1.5.sql @@ -1,4 +1,4 @@ -/* cstore_fdw/cstore_fdw--1.4.sql */ +/* cstore_fdw/cstore_fdw--1.5.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION cstore_fdw" to load this file. \quit @@ -31,7 +31,7 @@ RETURNS bigint AS 'MODULE_PATHNAME' LANGUAGE C STRICT; -CREATE FUNCTION cstore_clean_table_resources(oid) +CREATE OR REPLACE FUNCTION cstore_clean_table_resources(oid) RETURNS void AS 'MODULE_PATHNAME' LANGUAGE C STRICT; diff --git a/cstore_fdw.control b/cstore_fdw.control index 7b7a64b..d684b9b 100644 --- a/cstore_fdw.control +++ b/cstore_fdw.control @@ -1,5 +1,5 @@ # cstore_fdw extension comment = 'foreign-data wrapper for flat cstore access' -default_version = '1.4' +default_version = '1.5' module_pathname = '$libdir/cstore_fdw' relocatable = true diff --git a/cstore_fdw.h b/cstore_fdw.h index c0aa9c1..0727711 100644 --- a/cstore_fdw.h +++ b/cstore_fdw.h @@ -48,7 +48,7 @@ /* CStore file signature */ #define CSTORE_MAGIC_NUMBER "citus_cstore" #define CSTORE_VERSION_MAJOR 1 -#define CSTORE_VERSION_MINOR 4 +#define CSTORE_VERSION_MINOR 5 /* miscellaneous defines */ #define CSTORE_FDW_NAME "cstore_fdw"