Skip to content

Commit a6e5051

Browse files
committed
Merge branch 'master' into change-tablespace
2 parents c542bf2 + e9339f4 commit a6e5051

File tree

4 files changed

+129
-15
lines changed

4 files changed

+129
-15
lines changed

bin/expected/repack.out

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,51 @@ WARNING: relation "tbl_uk" must have a primary key or not-null unique keys
314314
\! pg_repack --dbname=contrib_regression --no-order --table=tbl_nn_puk
315315
WARNING: relation "tbl_nn_puk" must have a primary key or not-null unique keys
316316
-- => WARNING
317+
--
318+
-- pg_repack issue #3
319+
--
320+
CREATE TABLE issue3_1 (col1 int NOT NULL, col2 text NOT NULL);
321+
CREATE UNIQUE INDEX issue3_1_idx ON issue3_1 (col1, col2 DESC);
322+
SELECT repack.get_order_by('issue3_1_idx'::regclass::oid, 'issue3_1'::regclass::oid);
323+
get_order_by
324+
-----------------
325+
col1, col2 DESC
326+
(1 row)
327+
328+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_1
329+
CREATE TABLE issue3_2 (col1 int NOT NULL, col2 text NOT NULL);
330+
CREATE UNIQUE INDEX issue3_2_idx ON issue3_2 (col1 DESC, col2 text_pattern_ops);
331+
SELECT repack.get_order_by('issue3_2_idx'::regclass::oid, 'issue3_2'::regclass::oid);
332+
get_order_by
333+
---------------------------
334+
col1 DESC, col2 USING ~<~
335+
(1 row)
336+
337+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_2
338+
CREATE TABLE issue3_3 (col1 int NOT NULL, col2 text NOT NULL);
339+
CREATE UNIQUE INDEX issue3_3_idx ON issue3_3 (col1 DESC, col2 DESC);
340+
SELECT repack.get_order_by('issue3_3_idx'::regclass::oid, 'issue3_3'::regclass::oid);
341+
get_order_by
342+
----------------------
343+
col1 DESC, col2 DESC
344+
(1 row)
345+
346+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_3
347+
CREATE TABLE issue3_4 (col1 int NOT NULL, col2 text NOT NULL);
348+
CREATE UNIQUE INDEX issue3_4_idx ON issue3_4 (col1 NULLS FIRST, col2 text_pattern_ops DESC NULLS LAST);
349+
SELECT repack.get_order_by('issue3_4_idx'::regclass::oid, 'issue3_4'::regclass::oid);
350+
get_order_by
351+
--------------------------------------------------
352+
col1 NULLS FIRST, col2 DESC USING ~<~ NULLS LAST
353+
(1 row)
354+
355+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_4
356+
CREATE TABLE issue3_5 (col1 int NOT NULL, col2 text NOT NULL);
357+
CREATE UNIQUE INDEX issue3_5_idx ON issue3_5 (col1 DESC NULLS FIRST, col2 COLLATE "POSIX" DESC);
358+
SELECT repack.get_order_by('issue3_5_idx'::regclass::oid, 'issue3_5'::regclass::oid);
359+
get_order_by
360+
--------------------------------------
361+
col1 DESC, col2 COLLATE "POSIX" DESC
362+
(1 row)
363+
364+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_5

bin/sql/repack.sql

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,31 @@ CREATE UNIQUE INDEX tbl_nn_puk_pcol1_idx ON tbl_nn_puk(col1) WHERE col1 < 10;
187187
-- => OK
188188
\! pg_repack --dbname=contrib_regression --no-order --table=tbl_nn_puk
189189
-- => WARNING
190+
191+
--
192+
-- pg_repack issue #3
193+
--
194+
CREATE TABLE issue3_1 (col1 int NOT NULL, col2 text NOT NULL);
195+
CREATE UNIQUE INDEX issue3_1_idx ON issue3_1 (col1, col2 DESC);
196+
SELECT repack.get_order_by('issue3_1_idx'::regclass::oid, 'issue3_1'::regclass::oid);
197+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_1
198+
199+
CREATE TABLE issue3_2 (col1 int NOT NULL, col2 text NOT NULL);
200+
CREATE UNIQUE INDEX issue3_2_idx ON issue3_2 (col1 DESC, col2 text_pattern_ops);
201+
SELECT repack.get_order_by('issue3_2_idx'::regclass::oid, 'issue3_2'::regclass::oid);
202+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_2
203+
204+
CREATE TABLE issue3_3 (col1 int NOT NULL, col2 text NOT NULL);
205+
CREATE UNIQUE INDEX issue3_3_idx ON issue3_3 (col1 DESC, col2 DESC);
206+
SELECT repack.get_order_by('issue3_3_idx'::regclass::oid, 'issue3_3'::regclass::oid);
207+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_3
208+
209+
CREATE TABLE issue3_4 (col1 int NOT NULL, col2 text NOT NULL);
210+
CREATE UNIQUE INDEX issue3_4_idx ON issue3_4 (col1 NULLS FIRST, col2 text_pattern_ops DESC NULLS LAST);
211+
SELECT repack.get_order_by('issue3_4_idx'::regclass::oid, 'issue3_4'::regclass::oid);
212+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_4
213+
214+
CREATE TABLE issue3_5 (col1 int NOT NULL, col2 text NOT NULL);
215+
CREATE UNIQUE INDEX issue3_5_idx ON issue3_5 (col1 DESC NULLS FIRST, col2 COLLATE "POSIX" DESC);
216+
SELECT repack.get_order_by('issue3_5_idx'::regclass::oid, 'issue3_5'::regclass::oid);
217+
\! pg_repack --dbname=contrib_regression --no-order --table=issue3_5

lib/pg_repack.sql.in

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ $$
4444
$$
4545
LANGUAGE sql STABLE STRICT;
4646

47-
CREATE FUNCTION repack.get_index_keys(oid, oid) RETURNS text AS
48-
'MODULE_PATHNAME', 'repack_get_index_keys'
47+
CREATE FUNCTION repack.get_order_by(oid, oid) RETURNS text AS
48+
'MODULE_PATHNAME', 'repack_get_order_by'
4949
LANGUAGE C STABLE STRICT;
5050

5151
CREATE FUNCTION repack.get_create_index_type(oid, name) RETURNS text AS
@@ -185,7 +185,7 @@ CREATE VIEW repack.tables AS
185185
repack.get_drop_columns(R.oid, 'repack.table_' || R.oid) AS drop_columns,
186186
'DELETE FROM repack.log_' || R.oid AS delete_log,
187187
'LOCK TABLE ' || repack.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE' AS lock_table,
188-
repack.get_index_keys(CK.indexrelid, R.oid) AS ckey,
188+
repack.get_order_by(CK.indexrelid, R.oid) AS ckey,
189189
'SELECT * FROM repack.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek,
190190
'INSERT INTO repack.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert,
191191
'DELETE FROM repack.table_' || R.oid || ' WHERE ' || repack.get_compare_pkey(PK.indexrelid, '$1') AS sql_delete,

lib/repack.c

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ PG_MODULE_MAGIC;
4141
extern Datum PGUT_EXPORT repack_version(PG_FUNCTION_ARGS);
4242
extern Datum PGUT_EXPORT repack_trigger(PG_FUNCTION_ARGS);
4343
extern Datum PGUT_EXPORT repack_apply(PG_FUNCTION_ARGS);
44-
extern Datum PGUT_EXPORT repack_get_index_keys(PG_FUNCTION_ARGS);
44+
extern Datum PGUT_EXPORT repack_get_order_by(PG_FUNCTION_ARGS);
4545
extern Datum PGUT_EXPORT repack_indexdef(PG_FUNCTION_ARGS);
4646
extern Datum PGUT_EXPORT repack_swap(PG_FUNCTION_ARGS);
4747
extern Datum PGUT_EXPORT repack_drop(PG_FUNCTION_ARGS);
@@ -50,7 +50,7 @@ extern Datum PGUT_EXPORT repack_disable_autovacuum(PG_FUNCTION_ARGS);
5050
PG_FUNCTION_INFO_V1(repack_version);
5151
PG_FUNCTION_INFO_V1(repack_trigger);
5252
PG_FUNCTION_INFO_V1(repack_apply);
53-
PG_FUNCTION_INFO_V1(repack_get_index_keys);
53+
PG_FUNCTION_INFO_V1(repack_get_order_by);
5454
PG_FUNCTION_INFO_V1(repack_indexdef);
5555
PG_FUNCTION_INFO_V1(repack_swap);
5656
PG_FUNCTION_INFO_V1(repack_drop);
@@ -472,21 +472,51 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
472472
stmt->options = sql;
473473
}
474474

475+
/*
476+
* Parse the trailing ... [ COLLATE X ] [ DESC ] [ NULLS { FIRST | LAST } ] from an index
477+
* definition column.
478+
* Returned values point to token. \0's are inserted to separate parsed parts.
479+
*/
480+
static void
481+
parse_indexdef_col(char *token, char **desc, char **nulls, char **collate)
482+
{
483+
char *pos;
484+
485+
/* easier to walk backwards than to parse quotes and escapes... */
486+
if (NULL != (pos = strstr(token, " NULLS FIRST")))
487+
{
488+
*nulls = pos + 1;
489+
*pos = '\0';
490+
}
491+
else if (NULL != (pos = strstr(token, " NULLS LAST")))
492+
{
493+
*nulls = pos + 1;
494+
*pos = '\0';
495+
}
496+
if (NULL != (pos = strstr(token, " DESC")))
497+
{
498+
*desc = pos + 1;
499+
*pos = '\0';
500+
}
501+
if (NULL != (pos = strstr(token, " COLLATE ")))
502+
{
503+
*collate = pos + 1;
504+
*pos = '\0';
505+
}
506+
}
507+
475508
/**
476-
* @fn Datum repack_get_index_keys(PG_FUNCTION_ARGS)
509+
* @fn Datum repack_get_order_by(PG_FUNCTION_ARGS)
477510
* @brief Get key definition of the index.
478511
*
479-
* repack_get_index_keys(index, table)
512+
* repack_get_order_by(index, table)
480513
*
481514
* @param index Oid of target index.
482515
* @param table Oid of table of the index.
483516
* @retval Create index DDL for temp table.
484-
*
485-
* FIXME: this function is named get_index_keys, but actually returns
486-
* an expression for ORDER BY clause. get_order_by() might be a better name.
487517
*/
488518
Datum
489-
repack_get_index_keys(PG_FUNCTION_ARGS)
519+
repack_get_order_by(PG_FUNCTION_ARGS)
490520
{
491521
Oid index = PG_GETARG_OID(0);
492522
Oid table = PG_GETARG_OID(1);
@@ -514,12 +544,21 @@ repack_get_index_keys(PG_FUNCTION_ARGS)
514544
for (nattr = 0, next = stmt.columns; next; nattr++)
515545
{
516546
char *opcname;
547+
char *coldesc = NULL;
548+
char *colnulls = NULL;
549+
char *colcollate = NULL;
517550

518551
token = next;
519552
while (isspace((unsigned char) *token))
520553
token++;
521554
next = skip_until(index, next, ',');
555+
parse_indexdef_col(token, &coldesc, &colnulls, &colcollate);
522556
opcname = skip_until(index, token, ' ');
557+
appendStringInfoString(&str, token);
558+
if (colcollate)
559+
appendStringInfo(&str, " %s", colcollate);
560+
if (coldesc)
561+
appendStringInfo(&str, " %s", coldesc);
523562
if (opcname)
524563
{
525564
/* lookup default operator name from operator class */
@@ -556,12 +595,11 @@ repack_get_index_keys(PG_FUNCTION_ARGS)
556595
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
557596
strategy, opcintype, opcintype, opfamily);
558597

559-
560598
opcname[-1] = '\0';
561-
appendStringInfo(&str, "%s USING %s", token, get_opname(oprid));
599+
appendStringInfo(&str, " USING %s", get_opname(oprid));
562600
}
563-
else
564-
appendStringInfoString(&str, token);
601+
if (colnulls)
602+
appendStringInfo(&str, " %s", colnulls);
565603
if (next)
566604
appendStringInfoString(&str, ", ");
567605
}

0 commit comments

Comments
 (0)