Quote attribute names in deparsed index definition

Otherwise the emitted CREATE INDEX statement could be invalid.

Thanks to Oliver Rice for the report.
This commit is contained in:
Julien Rouhaud 2024-04-17 23:11:23 +08:00
parent bff1718a38
commit d102c8a640
5 changed files with 20 additions and 18 deletions

View file

@ -34,7 +34,7 @@ SELECT hypopg_reset();
-- Create INCLUDE index
SELECT COUNT(*) AS NB
FROM hypopg_create_index('CREATE INDEX ON hypo (id) INCLUDE (val)');
FROM hypopg_create_index('CREATE INDEX ON hypo (id) INCLUDE (val, "Id2")');
nb
----
1
@ -50,8 +50,8 @@ WHERE e ~ 'Index Only Scan.*<\d+>btree_hypo.*';
-- Deparse the index DDL
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg();
hypopg_get_indexdef
------------------------------------------------------------
CREATE INDEX ON public.hypo USING btree (id) INCLUDE (val)
hypopg_get_indexdef
-------------------------------------------------------------------
CREATE INDEX ON public.hypo USING btree (id) INCLUDE (val, "Id2")
(1 row)

View file

@ -12,7 +12,7 @@ END;
$_$
LANGUAGE plpgsql;
CREATE EXTENSION hypopg;
CREATE TABLE hypo (id integer, val text);
CREATE TABLE hypo (id integer, val text, "Id2" bigint);
INSERT INTO hypo SELECT i, 'line ' || i
FROM generate_series(1,100000) f(i);
ANALYZE hypo;
@ -159,10 +159,10 @@ WHERE e ~ 'Index.*<\d+>btree_hypo.*';
(1 row)
-- Deparse an index DDL, with almost every possible pathcode
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg_create_index('create index on hypo using btree(id desc, id desc nulls first, id desc nulls last, cast(md5(val) as bpchar) bpchar_pattern_ops) with (fillfactor = 10) WHERE id < 1000 AND id +1 %2 = 3');
hypopg_get_indexdef
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE INDEX ON public.hypo USING btree (id DESC, id DESC, id DESC NULLS LAST, ((md5(val))::bpchar) bpchar_pattern_ops) WITH (fillfactor = 10) WHERE ((id < 1000) AND ((id + (1 % 2)) = 3))
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg_create_index('create index on hypo using btree(id desc, "Id2" desc nulls first, id desc nulls last, cast(md5(val) as bpchar) bpchar_pattern_ops) with (fillfactor = 10) WHERE id < 1000 AND id +1 %2 = 3');
hypopg_get_indexdef
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE INDEX ON public.hypo USING btree (id DESC, "Id2" DESC, id DESC NULLS LAST, ((md5(val))::bpchar) bpchar_pattern_ops) WITH (fillfactor = 10) WHERE ((id < 1000) AND ((id + (1 % 2)) = 3))
(1 row)
-- Make sure the old Oid generator still works. Test it while keeping existing

View file

@ -1467,13 +1467,13 @@ hypopg_get_indexdef(PG_FUNCTION_ARGS)
if (entry->indexkeys[keyno] != 0)
{
int32 keycoltypmod;
char *attname;
#if PG_VERSION_NUM >= 110000
appendStringInfo(&buf, "%s", get_attname(entry->relid,
entry->indexkeys[keyno], false));
attname = get_attname(entry->relid, entry->indexkeys[keyno], false);
#else
appendStringInfo(&buf, "%s", get_attname(entry->relid,
entry->indexkeys[keyno]));
attname = get_attname(entry->relid, entry->indexkeys[keyno]);
#endif
appendStringInfo(&buf, "%s", quote_identifier(attname));
get_atttypetypmodcoll(entry->relid, entry->indexkeys[keyno],
&keycoltype, &keycoltypmod,
@ -1541,11 +1541,13 @@ hypopg_get_indexdef(PG_FUNCTION_ARGS)
appendStringInfo(&buf, " INCLUDE (");
for (keyno = entry->nkeycolumns; keyno < entry->ncolumns; keyno++)
{
char *attname;
if (keyno != entry->nkeycolumns)
appendStringInfo(&buf, ", ");
appendStringInfo(&buf, "%s", get_attname(entry->relid,
entry->indexkeys[keyno], false));
attname = get_attname(entry->relid, entry->indexkeys[keyno], false);
appendStringInfo(&buf, "%s", quote_identifier(attname));
}
appendStringInfo(&buf, ")");
}

View file

@ -21,7 +21,7 @@ SELECT hypopg_reset();
-- Create INCLUDE index
SELECT COUNT(*) AS NB
FROM hypopg_create_index('CREATE INDEX ON hypo (id) INCLUDE (val)');
FROM hypopg_create_index('CREATE INDEX ON hypo (id) INCLUDE (val, "Id2")');
-- Should use hypothetical index using an Index Only Scan
SELECT COUNT(*) FROM do_explain('SELECT val FROM hypo WHERE id = 1') e

View file

@ -14,7 +14,7 @@ LANGUAGE plpgsql;
CREATE EXTENSION hypopg;
CREATE TABLE hypo (id integer, val text);
CREATE TABLE hypo (id integer, val text, "Id2" bigint);
INSERT INTO hypo SELECT i, 'line ' || i
FROM generate_series(1,100000) f(i);
@ -102,7 +102,7 @@ SELECT COUNT(*) FROM do_explain('SELECT * FROM hypo WHERE md5(val) = md5(''line
WHERE e ~ 'Index.*<\d+>btree_hypo.*';
-- Deparse an index DDL, with almost every possible pathcode
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg_create_index('create index on hypo using btree(id desc, id desc nulls first, id desc nulls last, cast(md5(val) as bpchar) bpchar_pattern_ops) with (fillfactor = 10) WHERE id < 1000 AND id +1 %2 = 3');
SELECT hypopg_get_indexdef(indexrelid) FROM hypopg_create_index('create index on hypo using btree(id desc, "Id2" desc nulls first, id desc nulls last, cast(md5(val) as bpchar) bpchar_pattern_ops) with (fillfactor = 10) WHERE id < 1000 AND id +1 %2 = 3');
-- Make sure the old Oid generator still works. Test it while keeping existing
-- entries, as both should be able to coexist.