Skip to content

Commit

Permalink
Add upgrade tests for database level collation (#439)
Browse files Browse the repository at this point in the history
This commit adds upgrade tests for database level collation. For any collatable default constraint, PG adds EXPLICIT
collate clause for the default string (const node) iff the collation of the attribute is different from the collation of the
datatype stored in pg_type catalog. This is the result of invocation of pg_get_constraintdef() function which finally calls
get_const_expr(). To set the collation of the Const node, it calls get_const_collation() function where explicit COLLATE
clause is added based on the aforementioned condition.

Hence, when we create a database with non-default collation then the collatable columns get collated with the
database level collation (if not mentioned explicitly). But we store the collation of the collatable datatypes as server
level collation which fulfils the condition mentioned above. To solve this issue, we simply enclose the decompiled
DEFAULT expression by PARENTHESIS to avoid invalid syntax.

Extension PR: babelfish-for-postgresql/babelfish_extensions#2919

Task: BABEL-5141
Signed-off-by: Shameem Ahmed <[email protected]>
  • Loading branch information
ahmed-shameem authored Sep 24, 2024
1 parent ae1fa4d commit 0cfa922
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/bin/pg_dump/dump_babel_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,28 @@ fixTsqlDefaultExpr(Archive *fout, AttrDefInfo *attrDefInfo)
char *runtimeErrStr = "'An empty or space-only string cannot be converted into numeric/decimal data type'";
char *atttypname;

if (!isBabelfishDatabase(fout) ||
!strstr(source, runtimeErrStr) ||
/*
* We need to re-write the decompiled DEFAULT expression for non-default
* database level collation. Else, pg_dump adds explicit COLLATE clause
* after the DEFAULT expression as well. This creates two explicit
* COLLATE clause during dump -
* 1. For the column itself
* 2. For the default expression
* Eg: CREATE TABLE t1(a nvarchar(11) DEFAULT 'default') -->
* CREATE TABLE t1("a" "sys"."nvarchar" DEFAULT 'default'::"sys"."varchar" COLLATE <non_default_collation> COLLATE <non_default_collation>)
* This is an invalid syntax, hence it will fail during restore.
* Hence we re-write it to:
* CREATE TABLE t1("a" "sys"."nvarchar" DEFAULT ('default'::"sys"."varchar" COLLATE <non_default_collation>) COLLATE <non_default_collation>)
* by adding parenthesis. As adding parenthesis is optional in PG,
* we update all such default expressions for babelfish
*/
if (!isBabelfishDatabase(fout))
return;
attrDefInfo->adef_expr = psprintf("(%s)", source);
free(source);
source = attrDefInfo->adef_expr;

if (!strstr(source, runtimeErrStr) ||
strstr(source, runtimeErrFunc) ||
attrDefInfo->adnum < 1)
return;
Expand Down

0 comments on commit 0cfa922

Please sign in to comment.