Merge branch 'master' into change-tablespace
This commit is contained in:
commit
a6e50515ce
@ -314,3 +314,51 @@ WARNING: relation "tbl_uk" must have a primary key or not-null unique keys
|
|||||||
\! pg_repack --dbname=contrib_regression --no-order --table=tbl_nn_puk
|
\! pg_repack --dbname=contrib_regression --no-order --table=tbl_nn_puk
|
||||||
WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys
|
WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys
|
||||||
-- => WARNING
|
-- => WARNING
|
||||||
|
--
|
||||||
|
-- pg_repack issue #3
|
||||||
|
--
|
||||||
|
CREATE TABLE issue3_1 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_1_idx ON issue3_1 (col1, col2 DESC);
|
||||||
|
SELECT repack.get_order_by('issue3_1_idx'::regclass::oid, 'issue3_1'::regclass::oid);
|
||||||
|
get_order_by
|
||||||
|
-----------------
|
||||||
|
col1, col2 DESC
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_1
|
||||||
|
CREATE TABLE issue3_2 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_2_idx ON issue3_2 (col1 DESC, col2 text_pattern_ops);
|
||||||
|
SELECT repack.get_order_by('issue3_2_idx'::regclass::oid, 'issue3_2'::regclass::oid);
|
||||||
|
get_order_by
|
||||||
|
---------------------------
|
||||||
|
col1 DESC, col2 USING ~<~
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_2
|
||||||
|
CREATE TABLE issue3_3 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_3_idx ON issue3_3 (col1 DESC, col2 DESC);
|
||||||
|
SELECT repack.get_order_by('issue3_3_idx'::regclass::oid, 'issue3_3'::regclass::oid);
|
||||||
|
get_order_by
|
||||||
|
----------------------
|
||||||
|
col1 DESC, col2 DESC
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_3
|
||||||
|
CREATE TABLE issue3_4 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_4_idx ON issue3_4 (col1 NULLS FIRST, col2 text_pattern_ops DESC NULLS LAST);
|
||||||
|
SELECT repack.get_order_by('issue3_4_idx'::regclass::oid, 'issue3_4'::regclass::oid);
|
||||||
|
get_order_by
|
||||||
|
--------------------------------------------------
|
||||||
|
col1 NULLS FIRST, col2 DESC USING ~<~ NULLS LAST
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_4
|
||||||
|
CREATE TABLE issue3_5 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_5_idx ON issue3_5 (col1 DESC NULLS FIRST, col2 COLLATE "POSIX" DESC);
|
||||||
|
SELECT repack.get_order_by('issue3_5_idx'::regclass::oid, 'issue3_5'::regclass::oid);
|
||||||
|
get_order_by
|
||||||
|
--------------------------------------
|
||||||
|
col1 DESC, col2 COLLATE "POSIX" DESC
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_5
|
||||||
|
@ -187,3 +187,31 @@ CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10;
|
|||||||
-- => OK
|
-- => OK
|
||||||
\! pg_repack --dbname=contrib_regression --no-order --table=tbl_nn_puk
|
\! pg_repack --dbname=contrib_regression --no-order --table=tbl_nn_puk
|
||||||
-- => WARNING
|
-- => WARNING
|
||||||
|
|
||||||
|
--
|
||||||
|
-- pg_repack issue #3
|
||||||
|
--
|
||||||
|
CREATE TABLE issue3_1 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_1_idx ON issue3_1 (col1, col2 DESC);
|
||||||
|
SELECT repack.get_order_by('issue3_1_idx'::regclass::oid, 'issue3_1'::regclass::oid);
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_1
|
||||||
|
|
||||||
|
CREATE TABLE issue3_2 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_2_idx ON issue3_2 (col1 DESC, col2 text_pattern_ops);
|
||||||
|
SELECT repack.get_order_by('issue3_2_idx'::regclass::oid, 'issue3_2'::regclass::oid);
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_2
|
||||||
|
|
||||||
|
CREATE TABLE issue3_3 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_3_idx ON issue3_3 (col1 DESC, col2 DESC);
|
||||||
|
SELECT repack.get_order_by('issue3_3_idx'::regclass::oid, 'issue3_3'::regclass::oid);
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_3
|
||||||
|
|
||||||
|
CREATE TABLE issue3_4 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_4_idx ON issue3_4 (col1 NULLS FIRST, col2 text_pattern_ops DESC NULLS LAST);
|
||||||
|
SELECT repack.get_order_by('issue3_4_idx'::regclass::oid, 'issue3_4'::regclass::oid);
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_4
|
||||||
|
|
||||||
|
CREATE TABLE issue3_5 (col1 int NOT NULL, col2 text NOT NULL);
|
||||||
|
CREATE UNIQUE INDEX issue3_5_idx ON issue3_5 (col1 DESC NULLS FIRST, col2 COLLATE "POSIX" DESC);
|
||||||
|
SELECT repack.get_order_by('issue3_5_idx'::regclass::oid, 'issue3_5'::regclass::oid);
|
||||||
|
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_5
|
||||||
|
@ -44,8 +44,8 @@ $$
|
|||||||
$$
|
$$
|
||||||
LANGUAGE sql STABLE STRICT;
|
LANGUAGE sql STABLE STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION repack.get_index_keys(oid, oid) RETURNS text AS
|
CREATE FUNCTION repack.get_order_by(oid, oid) RETURNS text AS
|
||||||
'MODULE_PATHNAME', 'repack_get_index_keys'
|
'MODULE_PATHNAME', 'repack_get_order_by'
|
||||||
LANGUAGE C STABLE STRICT;
|
LANGUAGE C STABLE STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION repack.get_create_index_type(oid, name) RETURNS text AS
|
CREATE FUNCTION repack.get_create_index_type(oid, name) RETURNS text AS
|
||||||
@ -185,7 +185,7 @@ CREATE VIEW repack.tables AS
|
|||||||
repack.get_drop_columns(R.oid, 'repack.table_' || R.oid) AS drop_columns,
|
repack.get_drop_columns(R.oid, 'repack.table_' || R.oid) AS drop_columns,
|
||||||
'DELETE FROM repack.log_' || R.oid AS delete_log,
|
'DELETE FROM repack.log_' || R.oid AS delete_log,
|
||||||
'LOCK TABLE ' || repack.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE' AS lock_table,
|
'LOCK TABLE ' || repack.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE' AS lock_table,
|
||||||
repack.get_index_keys(CK.indexrelid, R.oid) AS ckey,
|
repack.get_order_by(CK.indexrelid, R.oid) AS ckey,
|
||||||
'SELECT * FROM repack.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek,
|
'SELECT * FROM repack.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek,
|
||||||
'INSERT INTO repack.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert,
|
'INSERT INTO repack.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert,
|
||||||
'DELETE FROM repack.table_' || R.oid || ' WHERE ' || repack.get_compare_pkey(PK.indexrelid, '$1') AS sql_delete,
|
'DELETE FROM repack.table_' || R.oid || ' WHERE ' || repack.get_compare_pkey(PK.indexrelid, '$1') AS sql_delete,
|
||||||
|
62
lib/repack.c
62
lib/repack.c
@ -41,7 +41,7 @@ PG_MODULE_MAGIC;
|
|||||||
extern Datum PGUT_EXPORT repack_version(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_version(PG_FUNCTION_ARGS);
|
||||||
extern Datum PGUT_EXPORT repack_trigger(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_trigger(PG_FUNCTION_ARGS);
|
||||||
extern Datum PGUT_EXPORT repack_apply(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_apply(PG_FUNCTION_ARGS);
|
||||||
extern Datum PGUT_EXPORT repack_get_index_keys(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_get_order_by(PG_FUNCTION_ARGS);
|
||||||
extern Datum PGUT_EXPORT repack_indexdef(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_indexdef(PG_FUNCTION_ARGS);
|
||||||
extern Datum PGUT_EXPORT repack_swap(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_swap(PG_FUNCTION_ARGS);
|
||||||
extern Datum PGUT_EXPORT repack_drop(PG_FUNCTION_ARGS);
|
extern Datum PGUT_EXPORT repack_drop(PG_FUNCTION_ARGS);
|
||||||
@ -50,7 +50,7 @@ extern Datum PGUT_EXPORT repack_disable_autovacuum(PG_FUNCTION_ARGS);
|
|||||||
PG_FUNCTION_INFO_V1(repack_version);
|
PG_FUNCTION_INFO_V1(repack_version);
|
||||||
PG_FUNCTION_INFO_V1(repack_trigger);
|
PG_FUNCTION_INFO_V1(repack_trigger);
|
||||||
PG_FUNCTION_INFO_V1(repack_apply);
|
PG_FUNCTION_INFO_V1(repack_apply);
|
||||||
PG_FUNCTION_INFO_V1(repack_get_index_keys);
|
PG_FUNCTION_INFO_V1(repack_get_order_by);
|
||||||
PG_FUNCTION_INFO_V1(repack_indexdef);
|
PG_FUNCTION_INFO_V1(repack_indexdef);
|
||||||
PG_FUNCTION_INFO_V1(repack_swap);
|
PG_FUNCTION_INFO_V1(repack_swap);
|
||||||
PG_FUNCTION_INFO_V1(repack_drop);
|
PG_FUNCTION_INFO_V1(repack_drop);
|
||||||
@ -472,21 +472,51 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
|
|||||||
stmt->options = sql;
|
stmt->options = sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the trailing ... [ COLLATE X ] [ DESC ] [ NULLS { FIRST | LAST } ] from an index
|
||||||
|
* definition column.
|
||||||
|
* Returned values point to token. \0's are inserted to separate parsed parts.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parse_indexdef_col(char *token, char **desc, char **nulls, char **collate)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
/* easier to walk backwards than to parse quotes and escapes... */
|
||||||
|
if (NULL != (pos = strstr(token, " NULLS FIRST")))
|
||||||
|
{
|
||||||
|
*nulls = pos + 1;
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
else if (NULL != (pos = strstr(token, " NULLS LAST")))
|
||||||
|
{
|
||||||
|
*nulls = pos + 1;
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
if (NULL != (pos = strstr(token, " DESC")))
|
||||||
|
{
|
||||||
|
*desc = pos + 1;
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
if (NULL != (pos = strstr(token, " COLLATE ")))
|
||||||
|
{
|
||||||
|
*collate = pos + 1;
|
||||||
|
*pos = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fn Datum repack_get_index_keys(PG_FUNCTION_ARGS)
|
* @fn Datum repack_get_order_by(PG_FUNCTION_ARGS)
|
||||||
* @brief Get key definition of the index.
|
* @brief Get key definition of the index.
|
||||||
*
|
*
|
||||||
* repack_get_index_keys(index, table)
|
* repack_get_order_by(index, table)
|
||||||
*
|
*
|
||||||
* @param index Oid of target index.
|
* @param index Oid of target index.
|
||||||
* @param table Oid of table of the index.
|
* @param table Oid of table of the index.
|
||||||
* @retval Create index DDL for temp table.
|
* @retval Create index DDL for temp table.
|
||||||
*
|
|
||||||
* FIXME: this function is named get_index_keys, but actually returns
|
|
||||||
* an expression for ORDER BY clause. get_order_by() might be a better name.
|
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
repack_get_index_keys(PG_FUNCTION_ARGS)
|
repack_get_order_by(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
Oid index = PG_GETARG_OID(0);
|
Oid index = PG_GETARG_OID(0);
|
||||||
Oid table = PG_GETARG_OID(1);
|
Oid table = PG_GETARG_OID(1);
|
||||||
@ -514,12 +544,21 @@ repack_get_index_keys(PG_FUNCTION_ARGS)
|
|||||||
for (nattr = 0, next = stmt.columns; next; nattr++)
|
for (nattr = 0, next = stmt.columns; next; nattr++)
|
||||||
{
|
{
|
||||||
char *opcname;
|
char *opcname;
|
||||||
|
char *coldesc = NULL;
|
||||||
|
char *colnulls = NULL;
|
||||||
|
char *colcollate = NULL;
|
||||||
|
|
||||||
token = next;
|
token = next;
|
||||||
while (isspace((unsigned char) *token))
|
while (isspace((unsigned char) *token))
|
||||||
token++;
|
token++;
|
||||||
next = skip_until(index, next, ',');
|
next = skip_until(index, next, ',');
|
||||||
|
parse_indexdef_col(token, &coldesc, &colnulls, &colcollate);
|
||||||
opcname = skip_until(index, token, ' ');
|
opcname = skip_until(index, token, ' ');
|
||||||
|
appendStringInfoString(&str, token);
|
||||||
|
if (colcollate)
|
||||||
|
appendStringInfo(&str, " %s", colcollate);
|
||||||
|
if (coldesc)
|
||||||
|
appendStringInfo(&str, " %s", coldesc);
|
||||||
if (opcname)
|
if (opcname)
|
||||||
{
|
{
|
||||||
/* lookup default operator name from operator class */
|
/* lookup default operator name from operator class */
|
||||||
@ -556,12 +595,11 @@ repack_get_index_keys(PG_FUNCTION_ARGS)
|
|||||||
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
|
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
|
||||||
strategy, opcintype, opcintype, opfamily);
|
strategy, opcintype, opcintype, opfamily);
|
||||||
|
|
||||||
|
|
||||||
opcname[-1] = '\0';
|
opcname[-1] = '\0';
|
||||||
appendStringInfo(&str, "%s USING %s", token, get_opname(oprid));
|
appendStringInfo(&str, " USING %s", get_opname(oprid));
|
||||||
}
|
}
|
||||||
else
|
if (colnulls)
|
||||||
appendStringInfoString(&str, token);
|
appendStringInfo(&str, " %s", colnulls);
|
||||||
if (next)
|
if (next)
|
||||||
appendStringInfoString(&str, ", ");
|
appendStringInfoString(&str, ", ");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user