@ -119,6 +119,7 @@ static bool get_db_info(const char *name, LOCKMODE lockmode,
int * encodingP , bool * dbIsTemplateP , bool * dbAllowConnP ,
TransactionId * dbFrozenXidP , MultiXactId * dbMinMultiP ,
Oid * dbTablespace , char * * dbCollate , char * * dbCtype , char * * dbIculocale ,
char * * dbIcurules ,
char * dbLocProvider ,
char * * dbCollversion ) ;
static void remove_dbtablespaces ( Oid db_id ) ;
@ -675,6 +676,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char * src_collate = NULL ;
char * src_ctype = NULL ;
char * src_iculocale = NULL ;
char * src_icurules = NULL ;
char src_locprovider = ' \0 ' ;
char * src_collversion = NULL ;
bool src_istemplate ;
@ -698,6 +700,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
DefElem * dcollate = NULL ;
DefElem * dctype = NULL ;
DefElem * diculocale = NULL ;
DefElem * dicurules = NULL ;
DefElem * dlocprovider = NULL ;
DefElem * distemplate = NULL ;
DefElem * dallowconnections = NULL ;
@ -710,6 +713,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
char * dbcollate = NULL ;
char * dbctype = NULL ;
char * dbiculocale = NULL ;
char * dbicurules = NULL ;
char dblocprovider = ' \0 ' ;
char * canonname ;
int encoding = - 1 ;
@ -775,6 +779,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errorConflictingDefElem ( defel , pstate ) ;
diculocale = defel ;
}
else if ( strcmp ( defel - > defname , " icu_rules " ) = = 0 )
{
if ( dicurules )
errorConflictingDefElem ( defel , pstate ) ;
dicurules = defel ;
}
else if ( strcmp ( defel - > defname , " locale_provider " ) = = 0 )
{
if ( dlocprovider )
@ -893,6 +903,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dbctype = defGetString ( dctype ) ;
if ( diculocale & & diculocale - > arg )
dbiculocale = defGetString ( diculocale ) ;
if ( dicurules & & dicurules - > arg )
dbicurules = defGetString ( dicurules ) ;
if ( dlocprovider & & dlocprovider - > arg )
{
char * locproviderstr = defGetString ( dlocprovider ) ;
@ -958,7 +970,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
& src_dboid , & src_owner , & src_encoding ,
& src_istemplate , & src_allowconn ,
& src_frozenxid , & src_minmxid , & src_deftablespace ,
& src_collate , & src_ctype , & src_iculocale , & src_locprovider ,
& src_collate , & src_ctype , & src_iculocale , & src_icurules , & src_ locprovider ,
& src_collversion ) )
ereport ( ERROR ,
( errcode ( ERRCODE_UNDEFINED_DATABASE ) ,
@ -1006,6 +1018,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
dblocprovider = src_locprovider ;
if ( dbiculocale = = NULL & & dblocprovider = = COLLPROVIDER_ICU )
dbiculocale = src_iculocale ;
if ( dbicurules = = NULL & & dblocprovider = = COLLPROVIDER_ICU )
dbicurules = src_icurules ;
/* Some encodings are client only */
if ( ! PG_VALID_BE_ENCODING ( encoding ) )
@ -1097,6 +1111,9 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
if ( dblocprovider = = COLLPROVIDER_ICU )
{
char * val1 ;
char * val2 ;
Assert ( dbiculocale ) ;
Assert ( src_iculocale ) ;
if ( strcmp ( dbiculocale , src_iculocale ) ! = 0 )
@ -1105,6 +1122,19 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
errmsg ( " new ICU locale (%s) is incompatible with the ICU locale of the template database (%s) " ,
dbiculocale , src_iculocale ) ,
errhint ( " Use the same ICU locale as in the template database, or use template0 as template. " ) ) ) ;
val1 = dbicurules ;
if ( ! val1 )
val1 = " " ;
val2 = src_icurules ;
if ( ! val2 )
val2 = " " ;
if ( strcmp ( val1 , val2 ) ! = 0 )
ereport ( ERROR ,
( errcode ( ERRCODE_INVALID_PARAMETER_VALUE ) ,
errmsg ( " new ICU collation rules (%s) are incompatible with the ICU collation rules of the template database (%s) " ,
val1 , val2 ) ,
errhint ( " Use the same ICU collation rules as in the template database, or use template0 as template. " ) ) ) ;
}
}
@ -1313,6 +1343,10 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
new_record [ Anum_pg_database_daticulocale - 1 ] = CStringGetTextDatum ( dbiculocale ) ;
else
new_record_nulls [ Anum_pg_database_daticulocale - 1 ] = true ;
if ( dbicurules )
new_record [ Anum_pg_database_daticurules - 1 ] = CStringGetTextDatum ( dbicurules ) ;
else
new_record_nulls [ Anum_pg_database_daticurules - 1 ] = true ;
if ( dbcollversion )
new_record [ Anum_pg_database_datcollversion - 1 ] = CStringGetTextDatum ( dbcollversion ) ;
else
@ -1526,7 +1560,7 @@ dropdb(const char *dbname, bool missing_ok, bool force)
pgdbrel = table_open ( DatabaseRelationId , RowExclusiveLock ) ;
if ( ! get_db_info ( dbname , AccessExclusiveLock , & db_id , NULL , NULL ,
& db_istemplate , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ) )
& db_istemplate , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ) )
{
if ( ! missing_ok )
{
@ -1726,7 +1760,7 @@ RenameDatabase(const char *oldname, const char *newname)
rel = table_open ( DatabaseRelationId , RowExclusiveLock ) ;
if ( ! get_db_info ( oldname , AccessExclusiveLock , & db_id , NULL , NULL ,
NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ) )
NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL ) )
ereport ( ERROR ,
( errcode ( ERRCODE_UNDEFINED_DATABASE ) ,
errmsg ( " database \" %s \" does not exist " , oldname ) ) ) ;
@ -1836,7 +1870,7 @@ movedb(const char *dbname, const char *tblspcname)
pgdbrel = table_open ( DatabaseRelationId , RowExclusiveLock ) ;
if ( ! get_db_info ( dbname , AccessExclusiveLock , & db_id , NULL , NULL ,
NULL , NULL , NULL , NULL , & src_tblspcoid , NULL , NULL , NULL , NULL , NULL ) )
NULL , NULL , NULL , NULL , & src_tblspcoid , NULL , NULL , NULL , NULL , NULL , NULL ) )
ereport ( ERROR ,
( errcode ( ERRCODE_UNDEFINED_DATABASE ) ,
errmsg ( " database \" %s \" does not exist " , dbname ) ) ) ;
@ -2599,6 +2633,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
int * encodingP , bool * dbIsTemplateP , bool * dbAllowConnP ,
TransactionId * dbFrozenXidP , MultiXactId * dbMinMultiP ,
Oid * dbTablespace , char * * dbCollate , char * * dbCtype , char * * dbIculocale ,
char * * dbIcurules ,
char * dbLocProvider ,
char * * dbCollversion )
{
@ -2715,6 +2750,14 @@ get_db_info(const char *name, LOCKMODE lockmode,
else
* dbIculocale = TextDatumGetCString ( datum ) ;
}
if ( dbIcurules )
{
datum = SysCacheGetAttr ( DATABASEOID , tuple , Anum_pg_database_daticurules , & isnull ) ;
if ( isnull )
* dbIcurules = NULL ;
else
* dbIcurules = TextDatumGetCString ( datum ) ;
}
if ( dbCollversion )
{
datum = SysCacheGetAttr ( DATABASEOID , tuple , Anum_pg_database_datcollversion , & isnull ) ;