Add support for column lists in ANALYZE commands

Was easy enough to extend to include this, so did so.
pull/1013/head
Jason Petersen 2016-12-16 16:16:33 -07:00
parent 48c43984cb
commit 51470eab75
No known key found for this signature in database
GPG Key ID: 9F1D3510D110ABA9
3 changed files with 81 additions and 22 deletions

View File

@ -114,6 +114,7 @@ static void ProcessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand)
static bool IsSupportedDistributedVacuumStmt(Oid relationId, VacuumStmt *vacuumStmt);
static List * VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt);
static StringInfo DeparseVacuumStmtPrefix(VacuumStmt *vacuumStmt);
static char * DeparseVacuumColumnNames(List *columnNameList);
/* Local functions forward declarations for unsupported command checks */
@ -988,13 +989,6 @@ IsSupportedDistributedVacuumStmt(Oid relationId, VacuumStmt *vacuumStmt)
"distributed %s commands", stmtName)));
}
if (vacuumStmt->va_cols != NIL)
{
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("specifying a column list is currently unsupported in "
"distributed %s commands", stmtName)));
}
return true;
}
@ -1012,6 +1006,7 @@ VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt)
uint64 jobId = INVALID_JOB_ID;
int taskId = 1;
StringInfo vacuumString = DeparseVacuumStmtPrefix(vacuumStmt);
const char *columnNames = DeparseVacuumColumnNames(vacuumStmt->va_cols);
const int vacuumPrefixLen = vacuumString->len;
Oid schemaId = get_rel_namespace(relationId);
char *schemaName = get_namespace_name(schemaId);
@ -1037,6 +1032,7 @@ VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt)
vacuumString->len = vacuumPrefixLen;
appendStringInfoString(vacuumString, shardName);
appendStringInfoString(vacuumString, columnNames);
task = CitusMakeNode(Task);
task->jobId = jobId;
@ -1086,9 +1082,8 @@ DeparseVacuumStmtPrefix(VacuumStmt *vacuumStmt)
vacuumFlags &= ~VACOPT_ANALYZE;
}
/* unsupported flags and options should have already been rejected */
/* unsupported flags should have already been rejected */
Assert((vacuumFlags & unsupportedFlags) == 0);
Assert(vacuumStmt->va_cols == NIL);
/* if no flags remain, exit early */
if (vacuumFlags == 0)
@ -1129,6 +1124,40 @@ DeparseVacuumStmtPrefix(VacuumStmt *vacuumStmt)
}
/*
* DeparseVacuumColumnNames joins the list of strings using commas as a
* delimiter. The whole thing is placed in parenthesis and set off with a
* single space in order to facilitate appending it to the end of any VACUUM
* or ANALYZE command which uses explicit column names. If the provided list
* is empty, this function returns an empty string to keep the calling code
* simplest.
*/
static char *
DeparseVacuumColumnNames(List *columnNameList)
{
StringInfo columnNames = makeStringInfo();
ListCell *columnNameCell = NULL;
if (columnNameList == NIL)
{
return columnNames->data;
}
appendStringInfoString(columnNames, " (");
foreach(columnNameCell, columnNameList)
{
char *columnName = strVal(lfirst(columnNameCell));
appendStringInfo(columnNames, "%s,", columnName);
}
columnNames->data[columnNames->len - 1] = ')';
return columnNames->data;
}
/*
* ErrorIfUnsupportedIndexStmt checks if the corresponding index statement is
* supported for distributed tables and errors out if it is not.

View File

@ -68,7 +68,7 @@ SELECT master_apply_delete_command('DELETE FROM sharded_table');
DROP TABLE sharded_table;
-- VACUUM tests
-- create a table with a single shard (for convenience)
CREATE TABLE dustbunnies (id integer, name text);
CREATE TABLE dustbunnies (id integer, name text, age integer);
SELECT master_create_distributed_table('dustbunnies', 'id', 'hash');
master_create_distributed_table
---------------------------------
@ -82,7 +82,7 @@ SELECT master_create_worker_shards('dustbunnies', 1, 2);
(1 row)
-- add some data to the distributed table
\copy dustbunnies from stdin with csv
\copy dustbunnies (id, name) from stdin with csv
-- following approach adapted from PostgreSQL's stats.sql file
-- save relevant stat counter values in refreshable view
\c - - - :worker_1_port
@ -201,6 +201,31 @@ WHERE oid='dustbunnies_990002'::regclass;
t
(1 row)
-- check there are no nulls in either column
SELECT attname, null_frac FROM pg_stats
WHERE tablename = 'dustbunnies_990002' ORDER BY attname;
attname | null_frac
---------+-----------
age | 1
id | 0
name | 0
(3 rows)
-- add NULL values, then perform column-specific ANALYZE
\c - - - :master_port
INSERT INTO dustbunnies VALUES (6, NULL, NULL);
ANALYZE dustbunnies (name);
-- verify that name's NULL ratio is updated but age's is not
\c - - - :worker_1_port
SELECT attname, null_frac FROM pg_stats
WHERE tablename = 'dustbunnies_990002' ORDER BY attname;
attname | null_frac
---------+-----------
age | 1
id | 0
name | 0.166667
(3 rows)
\c - - - :master_port
-- verify warning for unqualified VACUUM
VACUUM;
@ -212,11 +237,6 @@ VACUUM dustbunnies;
WARNING: not propagating VACUUM command to worker nodes
HINT: Set citus.enable_ddl_propagation to true in order to send targeted VACUUM commands to worker nodes.
SET citus.enable_ddl_propagation to DEFAULT;
-- verify error messages for unsupported options
VACUUM (ANALYZE) dustbunnies (id);
ERROR: specifying a column list is currently unsupported in distributed VACUUM commands
ANALYZE dustbunnies (id);
ERROR: specifying a column list is currently unsupported in distributed ANALYZE commands
-- TODO: support VERBOSE
-- VACUUM VERBOSE dustbunnies;
-- VACUUM (FULL, VERBOSE) dustbunnies;

View File

@ -44,12 +44,12 @@ DROP TABLE sharded_table;
-- VACUUM tests
-- create a table with a single shard (for convenience)
CREATE TABLE dustbunnies (id integer, name text);
CREATE TABLE dustbunnies (id integer, name text, age integer);
SELECT master_create_distributed_table('dustbunnies', 'id', 'hash');
SELECT master_create_worker_shards('dustbunnies', 1, 2);
-- add some data to the distributed table
\copy dustbunnies from stdin with csv
\copy dustbunnies (id, name) from stdin with csv
1,bugs
2,babs
3,buster
@ -146,6 +146,20 @@ VACUUM (FREEZE) dustbunnies;
SELECT relfrozenxid::text::integer > :frozenxid AS frozen_performed FROM pg_class
WHERE oid='dustbunnies_990002'::regclass;
-- check there are no nulls in either column
SELECT attname, null_frac FROM pg_stats
WHERE tablename = 'dustbunnies_990002' ORDER BY attname;
-- add NULL values, then perform column-specific ANALYZE
\c - - - :master_port
INSERT INTO dustbunnies VALUES (6, NULL, NULL);
ANALYZE dustbunnies (name);
-- verify that name's NULL ratio is updated but age's is not
\c - - - :worker_1_port
SELECT attname, null_frac FROM pg_stats
WHERE tablename = 'dustbunnies_990002' ORDER BY attname;
\c - - - :master_port
-- verify warning for unqualified VACUUM
VACUUM;
@ -155,10 +169,6 @@ SET citus.enable_ddl_propagation to false;
VACUUM dustbunnies;
SET citus.enable_ddl_propagation to DEFAULT;
-- verify error messages for unsupported options
VACUUM (ANALYZE) dustbunnies (id);
ANALYZE dustbunnies (id);
-- TODO: support VERBOSE
-- VACUUM VERBOSE dustbunnies;
-- VACUUM (FULL, VERBOSE) dustbunnies;