Fix crashes when cluster indexes have storage options (fillfactor, etc).
This commit is contained in:
parent
7084ec6de9
commit
a7a42b7bbf
@ -6,9 +6,9 @@ CREATE TABLE tbl_cluster (
|
||||
col1 int,
|
||||
col2 timestamp,
|
||||
","")" text,
|
||||
PRIMARY KEY (","")", col1)
|
||||
PRIMARY KEY (","")", col1) WITH (fillfactor = 75)
|
||||
) WITH (fillfactor = 70);
|
||||
CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops);
|
||||
CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75);
|
||||
ALTER TABLE tbl_cluster CLUSTER ON ","") cluster";
|
||||
CREATE TABLE tbl_only_pkey (
|
||||
col1 int PRIMARY KEY,
|
||||
@ -35,8 +35,9 @@ CREATE TABLE tbl_with_dropped_column (
|
||||
c2 text,
|
||||
d3 text
|
||||
);
|
||||
ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75);
|
||||
ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey;
|
||||
CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2);
|
||||
CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75);
|
||||
CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1);
|
||||
--
|
||||
-- insert data
|
||||
@ -85,8 +86,8 @@ SELECT * FROM tbl_with_dropped_column;
|
||||
col2 | timestamp without time zone |
|
||||
,") | text | not null
|
||||
Indexes:
|
||||
"tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1)
|
||||
",") cluster" btree (col2, length(","")"), ","")" text_pattern_ops) CLUSTER
|
||||
"tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) WITH (fillfactor=75)
|
||||
",") cluster" btree (col2, length(","")"), ","")" text_pattern_ops) WITH (fillfactor=75) CLUSTER
|
||||
|
||||
\d tbl_gistkey
|
||||
Table "public.tbl_gistkey"
|
||||
@ -126,8 +127,8 @@ Table "public.tbl_with_dropped_column"
|
||||
c2 | text |
|
||||
c3 | text |
|
||||
Indexes:
|
||||
"tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) CLUSTER
|
||||
"idx_c1c2" btree (c1, c2)
|
||||
"tbl_with_dropped_column_pkey" PRIMARY KEY, btree (id) WITH (fillfactor=75) CLUSTER
|
||||
"idx_c1c2" btree (c1, c2) WITH (fillfactor=75)
|
||||
"idx_c2c1" btree (c2, c1)
|
||||
|
||||
SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster;
|
||||
|
@ -144,8 +144,8 @@ option_find(int c, pgut_option opts1[], pgut_option opts2[])
|
||||
return NULL; /* not found */
|
||||
}
|
||||
|
||||
static void
|
||||
assign_option(pgut_option *opt, const char *optarg, pgut_optsrc src)
|
||||
void
|
||||
pgut_setopt(pgut_option *opt, const char *optarg, pgut_optsrc src)
|
||||
{
|
||||
const char *message;
|
||||
|
||||
@ -578,7 +578,7 @@ option_from_env(pgut_option options[])
|
||||
name[j] = '\0';
|
||||
|
||||
if ((value = getenv(name)) != NULL)
|
||||
assign_option(opt, value, SOURCE_ENV);
|
||||
pgut_setopt(opt, value, SOURCE_ENV);
|
||||
}
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ pgut_getopt(int argc, char **argv, pgut_option options[])
|
||||
while ((c = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1)
|
||||
{
|
||||
opt = option_find(c, default_options, options);
|
||||
assign_option(opt, optarg, SOURCE_CMDLINE);
|
||||
pgut_setopt(opt, optarg, SOURCE_CMDLINE);
|
||||
}
|
||||
|
||||
/* Read environment variables */
|
||||
@ -637,8 +637,8 @@ pgut_getopt(int argc, char **argv, pgut_option options[])
|
||||
}
|
||||
|
||||
/* compare two strings ignore cases and ignore -_ */
|
||||
static bool
|
||||
key_equals(const char *lhs, const char *rhs)
|
||||
bool
|
||||
pgut_keyeq(const char *lhs, const char *rhs)
|
||||
{
|
||||
for (; *lhs && *rhs; lhs++, rhs++)
|
||||
{
|
||||
@ -684,13 +684,13 @@ pgut_readopt(const char *path, pgut_option options[], int elevel)
|
||||
{
|
||||
pgut_option *opt = &options[i];
|
||||
|
||||
if (key_equals(key, opt->lname))
|
||||
if (pgut_keyeq(key, opt->lname))
|
||||
{
|
||||
if (opt->allowed == SOURCE_DEFAULT ||
|
||||
opt->allowed > SOURCE_FILE)
|
||||
elog(elevel, "option %s cannot specified in file", opt->lname);
|
||||
else if (opt->source <= SOURCE_FILE)
|
||||
assign_option(opt, value, SOURCE_FILE);
|
||||
pgut_setopt(opt, value, SOURCE_FILE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -105,6 +105,8 @@ extern bool interrupted;
|
||||
extern void help(bool details);
|
||||
extern int pgut_getopt(int argc, char **argv, pgut_option options[]);
|
||||
extern void pgut_readopt(const char *path, pgut_option options[], int elevel);
|
||||
extern void pgut_setopt(pgut_option *opt, const char *optarg, pgut_optsrc src);
|
||||
extern bool pgut_keyeq(const char *lhs, const char *rhs);
|
||||
extern void pgut_atexit_push(pgut_atexit_callback callback, void *userdata);
|
||||
extern void pgut_atexit_pop(pgut_atexit_callback callback, void *userdata);
|
||||
|
||||
|
@ -6,10 +6,10 @@ CREATE TABLE tbl_cluster (
|
||||
col1 int,
|
||||
col2 timestamp,
|
||||
","")" text,
|
||||
PRIMARY KEY (","")", col1)
|
||||
PRIMARY KEY (","")", col1) WITH (fillfactor = 75)
|
||||
) WITH (fillfactor = 70);
|
||||
|
||||
CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops);
|
||||
CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops) WITH (fillfactor = 75);
|
||||
ALTER TABLE tbl_cluster CLUSTER ON ","") cluster";
|
||||
|
||||
CREATE TABLE tbl_only_pkey (
|
||||
@ -42,8 +42,9 @@ CREATE TABLE tbl_with_dropped_column (
|
||||
c2 text,
|
||||
d3 text
|
||||
);
|
||||
ALTER INDEX tbl_with_dropped_column_pkey SET (fillfactor = 75);
|
||||
ALTER TABLE tbl_with_dropped_column CLUSTER ON tbl_with_dropped_column_pkey;
|
||||
CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2);
|
||||
CREATE INDEX idx_c1c2 ON tbl_with_dropped_column (c1, c2) WITH (fillfactor = 75);
|
||||
CREATE INDEX idx_c2c1 ON tbl_with_dropped_column (c2, c1);
|
||||
|
||||
--
|
||||
|
20
lib/reorg.c
20
lib/reorg.c
@ -350,6 +350,10 @@ skip_ident(Oid index, char *sql)
|
||||
return parse_error(index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip until 'end' character found. The 'end' character is replaced with \0.
|
||||
* Returns the next character of the 'end', or NULL if 'end' is not found.
|
||||
*/
|
||||
static char *
|
||||
skip_until(Oid index, char *sql, char end)
|
||||
{
|
||||
@ -391,8 +395,13 @@ skip_until(Oid index, char *sql, char end)
|
||||
|
||||
if (nopen == 0 && instr == 0)
|
||||
{
|
||||
*sql = '\0';
|
||||
return sql + 1;
|
||||
if (*sql)
|
||||
{
|
||||
*sql = '\0';
|
||||
return sql + 1;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* error */
|
||||
@ -427,7 +436,8 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
|
||||
parse_error(index);
|
||||
sql++;
|
||||
stmt->columns = sql;
|
||||
sql = skip_until(index, sql, ')');
|
||||
if ((sql = skip_until(index, sql, ')')) == NULL)
|
||||
parse_error(index);
|
||||
/* options */
|
||||
stmt->options = sql;
|
||||
}
|
||||
@ -467,7 +477,7 @@ reorg_get_index_keys(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
|
||||
initStringInfo(&str);
|
||||
for (nattr = 0, next = stmt.columns; *next; nattr++)
|
||||
for (nattr = 0, next = stmt.columns; next; nattr++)
|
||||
{
|
||||
char *opcname;
|
||||
|
||||
@ -544,7 +554,7 @@ reorg_get_index_keys(PG_FUNCTION_ARGS)
|
||||
}
|
||||
else
|
||||
appendStringInfoString(&str, token);
|
||||
if (*next)
|
||||
if (next)
|
||||
appendStringInfoChar(&str, ',');
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user