pull/7240/head
Onur Tirtir 2023-11-13 18:00:42 +03:00
parent 7e15939e50
commit c1dce6fc2b
1 changed files with 75 additions and 99 deletions

View File

@ -49,11 +49,16 @@
*/ */
typedef struct DatabaseCollationInfo typedef struct DatabaseCollationInfo
{ {
char *collation; char *datcollate;
char *ctype; char *datctype;
#if PG_VERSION_NUM >= PG_VERSION_15 #if PG_VERSION_NUM >= PG_VERSION_15
char *icu_locale; char *daticulocale;
char *collversion; char *datcollversion;
#endif
#if PG_VERSION_NUM >= PG_VERSION_16
char *daticurules;
#endif #endif
} DatabaseCollationInfo; } DatabaseCollationInfo;
@ -485,15 +490,14 @@ GetTablespaceName(Oid tablespaceOid)
/* /*
* GetDatabaseCollation gets oid of a database and returns all the collation related information * GetDatabaseCollation gets oid of a database and returns all the collation related information
* We need this method since collation related info in Form_pg_database is not accessible * We need this method since collation related info in Form_pg_database is not accessible.
*/ */
static DatabaseCollationInfo static DatabaseCollationInfo
GetDatabaseCollation(Oid dbOid) GetDatabaseCollation(Oid dbOid)
{ {
DatabaseCollationInfo info; DatabaseCollationInfo info;
bool isNull; memset(&info, 0, sizeof(DatabaseCollationInfo));
Snapshot snapshot = RegisterSnapshot(GetLatestSnapshot());
Relation rel = table_open(DatabaseRelationId, AccessShareLock); Relation rel = table_open(DatabaseRelationId, AccessShareLock);
HeapTuple tup = get_catalog_object_by_oid(rel, Anum_pg_database_oid, dbOid); HeapTuple tup = get_catalog_object_by_oid(rel, Anum_pg_database_oid, dbOid);
if (!HeapTupleIsValid(tup)) if (!HeapTupleIsValid(tup))
@ -501,55 +505,44 @@ GetDatabaseCollation(Oid dbOid)
elog(ERROR, "cache lookup failed for database %u", dbOid); elog(ERROR, "cache lookup failed for database %u", dbOid);
} }
bool isNull = false;
TupleDesc tupdesc = RelationGetDescr(rel); TupleDesc tupdesc = RelationGetDescr(rel);
Datum collationDatum = heap_getattr(tup, Anum_pg_database_datcollate, tupdesc, Datum collationDatum = heap_getattr(tup, Anum_pg_database_datcollate, tupdesc,
&isNull); &isNull);
if (isNull) info.datcollate = TextDatumGetCString(collationDatum);
{
info.collation = NULL;
}
else
{
info.collation = TextDatumGetCString(collationDatum);
}
Datum ctypeDatum = heap_getattr(tup, Anum_pg_database_datctype, tupdesc, &isNull); Datum ctypeDatum = heap_getattr(tup, Anum_pg_database_datctype, tupdesc, &isNull);
if (isNull) info.datctype = TextDatumGetCString(ctypeDatum);
{
info.ctype = NULL;
}
else
{
info.ctype = TextDatumGetCString(ctypeDatum);
}
#if PG_VERSION_NUM >= PG_VERSION_15 #if PG_VERSION_NUM >= PG_VERSION_15
Datum icuLocaleDatum = heap_getattr(tup, Anum_pg_database_daticulocale, tupdesc, Datum icuLocaleDatum = heap_getattr(tup, Anum_pg_database_daticulocale, tupdesc,
&isNull); &isNull);
if (isNull) if (!isNull)
{ {
info.icu_locale = NULL; info.daticulocale = TextDatumGetCString(icuLocaleDatum);
}
else
{
info.icu_locale = TextDatumGetCString(icuLocaleDatum);
} }
Datum collverDatum = heap_getattr(tup, Anum_pg_database_datcollversion, tupdesc, Datum collverDatum = heap_getattr(tup, Anum_pg_database_datcollversion, tupdesc,
&isNull); &isNull);
if (isNull) if (!isNull)
{ {
info.collversion = NULL; info.datcollversion = TextDatumGetCString(collverDatum);
} }
else #endif
#if PG_VERSION_NUM >= PG_VERSION_16
Datum icurulesDatum = heap_getattr(tup, Anum_pg_database_daticurules, tupdesc,
&isNull);
if (!isNull)
{ {
info.collversion = TextDatumGetCString(collverDatum); info.daticurules = TextDatumGetCString(icurulesDatum);
} }
#endif #endif
table_close(rel, AccessShareLock); table_close(rel, AccessShareLock);
UnregisterSnapshot(snapshot);
heap_freetuple(tup); heap_freetuple(tup);
return info; return info;
@ -577,13 +570,11 @@ GetLocaleProviderString(char datlocprovider)
return "icu"; return "icu";
} }
case 'l':
{
return "locale";
}
default: default:
return ""; {
ereport(ERROR, (errmsg("unexpected datlocprovider value: %c",
datlocprovider)));
}
} }
} }
@ -610,68 +601,53 @@ GenerateCreateDatabaseStatementFromPgDatabase(Form_pg_database databaseForm)
appendStringInfo(&str, "CREATE DATABASE %s", appendStringInfo(&str, "CREATE DATABASE %s",
quote_identifier(NameStr(databaseForm->datname))); quote_identifier(NameStr(databaseForm->datname)));
if (databaseForm->datdba != InvalidOid) appendStringInfo(&str, " CONNECTION LIMIT %d", databaseForm->datconnlimit);
{
appendStringInfo(&str, " OWNER = %s",
quote_literal_cstr(GetUserNameFromId(databaseForm->datdba,
false)));
}
if (databaseForm->encoding != -1)
{
appendStringInfo(&str, " ENCODING = %s",
quote_literal_cstr(pg_encoding_to_char(databaseForm->encoding)));
}
if (collInfo.collation != NULL)
{
appendStringInfo(&str, " LC_COLLATE = %s", quote_literal_cstr(
collInfo.collation));
}
if (collInfo.ctype != NULL)
{
appendStringInfo(&str, " LC_CTYPE = %s", quote_literal_cstr(collInfo.ctype));
}
#if PG_VERSION_NUM >= PG_VERSION_15
if (collInfo.icu_locale != NULL)
{
appendStringInfo(&str, " ICU_LOCALE = %s", quote_literal_cstr(
collInfo.icu_locale));
}
if (databaseForm->datlocprovider != 0)
{
appendStringInfo(&str, " LOCALE_PROVIDER = %s",
quote_literal_cstr(GetLocaleProviderString(
databaseForm->datlocprovider)));
}
if (collInfo.collversion != NULL)
{
appendStringInfo(&str, " COLLATION_VERSION = %s", quote_literal_cstr(
collInfo.collversion));
}
#endif
if (databaseForm->dattablespace != InvalidOid)
{
appendStringInfo(&str, " TABLESPACE = %s",
quote_identifier(GetTablespaceName(
databaseForm->dattablespace)));
}
appendStringInfo(&str, " ALLOW_CONNECTIONS = %s", appendStringInfo(&str, " ALLOW_CONNECTIONS = %s",
quote_literal_cstr(databaseForm->datallowconn ? "true" : "false")); quote_literal_cstr(databaseForm->datallowconn ? "true" : "false"));
if (databaseForm->datconnlimit >= 0)
{
appendStringInfo(&str, " CONNECTION LIMIT %d", databaseForm->datconnlimit);
}
appendStringInfo(&str, " IS_TEMPLATE = %s", appendStringInfo(&str, " IS_TEMPLATE = %s",
quote_literal_cstr(databaseForm->datistemplate ? "true" : "false")); quote_literal_cstr(databaseForm->datistemplate ? "true" : "false"));
appendStringInfo(&str, " LC_COLLATE = %s",
quote_literal_cstr(collInfo.datcollate));
appendStringInfo(&str, " LC_CTYPE = %s", quote_literal_cstr(collInfo.datctype));
appendStringInfo(&str, " OWNER = %s",
quote_literal_cstr(GetUserNameFromId(databaseForm->datdba, false)));
appendStringInfo(&str, " TABLESPACE = %s",
quote_identifier(GetTablespaceName(databaseForm->dattablespace)));
appendStringInfo(&str, " ENCODING = %s",
quote_literal_cstr(pg_encoding_to_char(databaseForm->encoding)));
#if PG_VERSION_NUM >= PG_VERSION_15
if (collInfo.datcollversion != NULL)
{
appendStringInfo(&str, " COLLATION_VERSION = %s",
quote_literal_cstr(collInfo.datcollversion));
}
if (collInfo.daticulocale != NULL)
{
appendStringInfo(&str, " ICU_LOCALE = %s", quote_literal_cstr(
collInfo.daticulocale));
}
appendStringInfo(&str, " LOCALE_PROVIDER = %s",
quote_literal_cstr(GetLocaleProviderString(
databaseForm->datlocprovider)));
#endif
#if PG_VERSION_NUM >= PG_VERSION_16
if (collInfo.daticurules != NULL)
{
appendStringInfo(&str, " ICU_RULES = %s", quote_literal_cstr(
collInfo.daticurules));
}
#endif
return str.data; return str.data;
} }