mirror of https://github.com/citusdata/citus.git
Add support for column lists in ANALYZE commands
Was easy enough to extend to include this, so did so.pull/1013/head
parent
48c43984cb
commit
51470eab75
|
@ -114,6 +114,7 @@ static void ProcessVacuumStmt(VacuumStmt *vacuumStmt, const char *vacuumCommand)
|
||||||
static bool IsSupportedDistributedVacuumStmt(Oid relationId, VacuumStmt *vacuumStmt);
|
static bool IsSupportedDistributedVacuumStmt(Oid relationId, VacuumStmt *vacuumStmt);
|
||||||
static List * VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt);
|
static List * VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt);
|
||||||
static StringInfo DeparseVacuumStmtPrefix(VacuumStmt *vacuumStmt);
|
static StringInfo DeparseVacuumStmtPrefix(VacuumStmt *vacuumStmt);
|
||||||
|
static char * DeparseVacuumColumnNames(List *columnNameList);
|
||||||
|
|
||||||
|
|
||||||
/* Local functions forward declarations for unsupported command checks */
|
/* Local functions forward declarations for unsupported command checks */
|
||||||
|
@ -988,13 +989,6 @@ IsSupportedDistributedVacuumStmt(Oid relationId, VacuumStmt *vacuumStmt)
|
||||||
"distributed %s commands", stmtName)));
|
"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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1012,6 +1006,7 @@ VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt)
|
||||||
uint64 jobId = INVALID_JOB_ID;
|
uint64 jobId = INVALID_JOB_ID;
|
||||||
int taskId = 1;
|
int taskId = 1;
|
||||||
StringInfo vacuumString = DeparseVacuumStmtPrefix(vacuumStmt);
|
StringInfo vacuumString = DeparseVacuumStmtPrefix(vacuumStmt);
|
||||||
|
const char *columnNames = DeparseVacuumColumnNames(vacuumStmt->va_cols);
|
||||||
const int vacuumPrefixLen = vacuumString->len;
|
const int vacuumPrefixLen = vacuumString->len;
|
||||||
Oid schemaId = get_rel_namespace(relationId);
|
Oid schemaId = get_rel_namespace(relationId);
|
||||||
char *schemaName = get_namespace_name(schemaId);
|
char *schemaName = get_namespace_name(schemaId);
|
||||||
|
@ -1037,6 +1032,7 @@ VacuumTaskList(Oid relationId, VacuumStmt *vacuumStmt)
|
||||||
|
|
||||||
vacuumString->len = vacuumPrefixLen;
|
vacuumString->len = vacuumPrefixLen;
|
||||||
appendStringInfoString(vacuumString, shardName);
|
appendStringInfoString(vacuumString, shardName);
|
||||||
|
appendStringInfoString(vacuumString, columnNames);
|
||||||
|
|
||||||
task = CitusMakeNode(Task);
|
task = CitusMakeNode(Task);
|
||||||
task->jobId = jobId;
|
task->jobId = jobId;
|
||||||
|
@ -1086,9 +1082,8 @@ DeparseVacuumStmtPrefix(VacuumStmt *vacuumStmt)
|
||||||
vacuumFlags &= ~VACOPT_ANALYZE;
|
vacuumFlags &= ~VACOPT_ANALYZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unsupported flags and options should have already been rejected */
|
/* unsupported flags should have already been rejected */
|
||||||
Assert((vacuumFlags & unsupportedFlags) == 0);
|
Assert((vacuumFlags & unsupportedFlags) == 0);
|
||||||
Assert(vacuumStmt->va_cols == NIL);
|
|
||||||
|
|
||||||
/* if no flags remain, exit early */
|
/* if no flags remain, exit early */
|
||||||
if (vacuumFlags == 0)
|
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
|
* ErrorIfUnsupportedIndexStmt checks if the corresponding index statement is
|
||||||
* supported for distributed tables and errors out if it is not.
|
* supported for distributed tables and errors out if it is not.
|
||||||
|
|
|
@ -68,7 +68,7 @@ SELECT master_apply_delete_command('DELETE FROM sharded_table');
|
||||||
DROP TABLE sharded_table;
|
DROP TABLE sharded_table;
|
||||||
-- VACUUM tests
|
-- VACUUM tests
|
||||||
-- create a table with a single shard (for convenience)
|
-- 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_distributed_table('dustbunnies', 'id', 'hash');
|
||||||
master_create_distributed_table
|
master_create_distributed_table
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
@ -82,7 +82,7 @@ SELECT master_create_worker_shards('dustbunnies', 1, 2);
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- add some data to the distributed table
|
-- 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
|
-- following approach adapted from PostgreSQL's stats.sql file
|
||||||
-- save relevant stat counter values in refreshable view
|
-- save relevant stat counter values in refreshable view
|
||||||
\c - - - :worker_1_port
|
\c - - - :worker_1_port
|
||||||
|
@ -201,6 +201,31 @@ WHERE oid='dustbunnies_990002'::regclass;
|
||||||
t
|
t
|
||||||
(1 row)
|
(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
|
\c - - - :master_port
|
||||||
-- verify warning for unqualified VACUUM
|
-- verify warning for unqualified VACUUM
|
||||||
VACUUM;
|
VACUUM;
|
||||||
|
@ -212,11 +237,6 @@ VACUUM dustbunnies;
|
||||||
WARNING: not propagating VACUUM command to worker nodes
|
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.
|
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;
|
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
|
-- TODO: support VERBOSE
|
||||||
-- VACUUM VERBOSE dustbunnies;
|
-- VACUUM VERBOSE dustbunnies;
|
||||||
-- VACUUM (FULL, VERBOSE) dustbunnies;
|
-- VACUUM (FULL, VERBOSE) dustbunnies;
|
||||||
|
|
|
@ -44,12 +44,12 @@ DROP TABLE sharded_table;
|
||||||
-- VACUUM tests
|
-- VACUUM tests
|
||||||
|
|
||||||
-- create a table with a single shard (for convenience)
|
-- 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_distributed_table('dustbunnies', 'id', 'hash');
|
||||||
SELECT master_create_worker_shards('dustbunnies', 1, 2);
|
SELECT master_create_worker_shards('dustbunnies', 1, 2);
|
||||||
|
|
||||||
-- add some data to the distributed table
|
-- add some data to the distributed table
|
||||||
\copy dustbunnies from stdin with csv
|
\copy dustbunnies (id, name) from stdin with csv
|
||||||
1,bugs
|
1,bugs
|
||||||
2,babs
|
2,babs
|
||||||
3,buster
|
3,buster
|
||||||
|
@ -146,6 +146,20 @@ VACUUM (FREEZE) dustbunnies;
|
||||||
SELECT relfrozenxid::text::integer > :frozenxid AS frozen_performed FROM pg_class
|
SELECT relfrozenxid::text::integer > :frozenxid AS frozen_performed FROM pg_class
|
||||||
WHERE oid='dustbunnies_990002'::regclass;
|
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
|
\c - - - :master_port
|
||||||
-- verify warning for unqualified VACUUM
|
-- verify warning for unqualified VACUUM
|
||||||
VACUUM;
|
VACUUM;
|
||||||
|
@ -155,10 +169,6 @@ SET citus.enable_ddl_propagation to false;
|
||||||
VACUUM dustbunnies;
|
VACUUM dustbunnies;
|
||||||
SET citus.enable_ddl_propagation to DEFAULT;
|
SET citus.enable_ddl_propagation to DEFAULT;
|
||||||
|
|
||||||
-- verify error messages for unsupported options
|
|
||||||
VACUUM (ANALYZE) dustbunnies (id);
|
|
||||||
ANALYZE dustbunnies (id);
|
|
||||||
|
|
||||||
-- TODO: support VERBOSE
|
-- TODO: support VERBOSE
|
||||||
-- VACUUM VERBOSE dustbunnies;
|
-- VACUUM VERBOSE dustbunnies;
|
||||||
-- VACUUM (FULL, VERBOSE) dustbunnies;
|
-- VACUUM (FULL, VERBOSE) dustbunnies;
|
||||||
|
|
Loading…
Reference in New Issue