8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 21:23:04 +01:00

Fix character set and collation output for character sets with altered default collation

This commit is contained in:
Dimitry Sibiryakov 2023-09-14 18:10:32 +02:00 committed by Alexander Peshkov
parent 7c822e41f9
commit 72f55f2160
4 changed files with 73 additions and 112 deletions

View File

@ -397,14 +397,12 @@ int EXTRACT_list_table(const SCHAR* relation_name,
// International character sets
// Print only the character set
if ((FLD.RDB$FIELD_TYPE == blr_text || FLD.RDB$FIELD_TYPE == blr_varying) &&
!RFR.RDB$COLLATION_ID.NULL && RFR.RDB$COLLATION_ID)
!RFR.RDB$COLLATION_ID.NULL)
{
char_sets[0] = '\0';
// There is no need to print character set for domain at all because it cannot be overriden.
// Collation will be printed later.
collation = RFR.RDB$COLLATION_ID;
char_set_id = FLD.RDB$CHARACTER_SET_ID;
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, true, false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
}
}
else
@ -461,8 +459,8 @@ int EXTRACT_list_table(const SCHAR* relation_name,
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
char_set_id = FLD.RDB$CHARACTER_SET_ID;
if ((char_set_id != default_char_set_id) || collation)
ISQL_get_character_sets (char_set_id, 0, false, false, true, char_sets);
if (char_set_id != default_char_set_id)
ISQL_get_character_sets(char_set_id, 0, true, false, false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
// CVC: Someone deleted the code that checks intchar when handling collations
@ -482,11 +480,11 @@ int EXTRACT_list_table(const SCHAR* relation_name,
if (!FLD.RDB$COMPUTED_SOURCE.NULL)
ISQL_print_validation (isqlGlob.Out, &FLD.RDB$COMPUTED_SOURCE, true, fbTrans);
}
else if (collation)
else if (!RFR.RDB$COLLATION_ID.NULL)
{
SCHAR collate_name[CHARSET_COLLATE_SIZE];
collate_name[0] = '\0';
ISQL_get_character_sets(char_set_id, collation, true, false, true, collate_name);
ISQL_get_character_sets(char_set_id, collation, false, true, false, true, collate_name);
if (collate_name[0])
{
@ -582,10 +580,10 @@ int EXTRACT_list_table(const SCHAR* relation_name,
// Handle collations after defaults
if (collation)
if (!RFR.RDB$COLLATION_ID.NULL)
{
char_sets[0] = '\0';
ISQL_get_character_sets (char_set_id, collation, true, false, true, char_sets);
ISQL_get_character_sets(char_set_id, collation, false, true, false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
}
@ -819,10 +817,10 @@ static void get_procedure_args(const char* proc_name)
// International character sets
// Print only the collation
if ((FLD.RDB$FIELD_TYPE == blr_text || FLD.RDB$FIELD_TYPE == blr_varying) &&
!prm_collation_id_null && prm_collation_id)
!prm_collation_id_null)
{
char_sets[0] = '\0';
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, prm_collation_id, true,
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, prm_collation_id, false, true,
!prm_null_flag_null && prm_null_flag, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
@ -878,7 +876,7 @@ static void get_procedure_args(const char* proc_name)
if (FLD.RDB$CHARACTER_SET_ID.NULL)
FLD.RDB$CHARACTER_SET_ID = 0;
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, collation, false,
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, collation, true, true,
!prm_null_flag_null && prm_null_flag, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
@ -1043,10 +1041,10 @@ static void get_function_args_ods12(const char* func_name, USHORT out_arg)
// International character sets
// Print only the collation
if ((FLD.RDB$FIELD_TYPE == blr_text || FLD.RDB$FIELD_TYPE == blr_varying) &&
!prm_collation_id_null && prm_collation_id)
!prm_collation_id_null)
{
char_sets[0] = '\0';
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, prm_collation_id, true,
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, prm_collation_id, false, true,
!prm_null_flag_null && prm_null_flag, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
@ -1102,7 +1100,7 @@ static void get_function_args_ods12(const char* func_name, USHORT out_arg)
if (FLD.RDB$CHARACTER_SET_ID.NULL)
FLD.RDB$CHARACTER_SET_ID = 0;
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, collation, false,
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, collation, true, true,
!prm_null_flag_null && prm_null_flag, true, char_sets);
if (char_sets[0])
@ -2333,10 +2331,9 @@ static void list_domain_table(const SCHAR* table_name, SSHORT default_char_set_i
{
char_sets[0] = 0;
if ((FLD.RDB$CHARACTER_SET_ID != default_char_set_id) ||
(!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0))
if (FLD.RDB$CHARACTER_SET_ID != default_char_set_id)
{
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, false, false, true,
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, 0, true, false, false, true,
char_sets);
}
if (char_sets[0])
@ -2361,14 +2358,13 @@ static void list_domain_table(const SCHAR* table_name, SSHORT default_char_set_i
order is the default for the character set being used, then no collation
order will be shown ( because it isn't needed ).
If the collation id is 0, then the default for the character set is
being used so there is no need to retrieve the collation information.*/
Even if the collation id is 0, it may be non-default for the character set.*/
if (!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0)
if (!FLD.RDB$COLLATION_ID.NULL)
{
char_sets[0] = 0;
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, FLD.RDB$COLLATION_ID, true, false,
true, char_sets);
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, FLD.RDB$COLLATION_ID, false, true,
false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
@ -2460,10 +2456,9 @@ static void list_domains(SSHORT default_char_set_id)
FLD.RDB$FIELD_SUB_TYPE != fb_text_subtype_text))
{
char_sets[0] = 0;
if ((FLD.RDB$CHARACTER_SET_ID != default_char_set_id) ||
(!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0))
if (FLD.RDB$CHARACTER_SET_ID != default_char_set_id)
{
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, false, false, true,
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, 0, true, false, false, true,
char_sets);
}
if (char_sets[0])
@ -2484,14 +2479,13 @@ static void list_domains(SSHORT default_char_set_id)
order is the default for the character set being used, then no collation
order will be shown ( because it isn't needed
If the collation id is 0, then the default for the character set is
being used so there is no need to retrieve the collation information.*/
Even if the collation id is 0, it may be non-default for the character.*/
if (!FLD.RDB$COLLATION_ID.NULL && FLD.RDB$COLLATION_ID != 0)
if (!FLD.RDB$COLLATION_ID.NULL)
{
char_sets[0] = 0;
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, FLD.RDB$COLLATION_ID, true, false,
true, char_sets);
ISQL_get_character_sets(FLD.RDB$CHARACTER_SET_ID, FLD.RDB$COLLATION_ID, false, true,
false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
@ -2630,13 +2624,12 @@ static void listRelationComputed(LegacyTables flag, SSHORT default_char_set_id)
// International character sets
// Print only the character set
if ((FLD.RDB$FIELD_TYPE == blr_text || FLD.RDB$FIELD_TYPE == blr_varying) &&
!RFR.RDB$COLLATION_ID.NULL && RFR.RDB$COLLATION_ID)
!RFR.RDB$COLLATION_ID.NULL)
{
char_sets[0] = '\0';
collation = RFR.RDB$COLLATION_ID;
char_set_id = FLD.RDB$CHARACTER_SET_ID;
ISQL_get_character_sets (FLD.RDB$CHARACTER_SET_ID, 0, true, false, true,
char_sets);
ISQL_get_character_sets(char_set_id, collation, false, true, false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
@ -2696,8 +2689,8 @@ static void listRelationComputed(LegacyTables flag, SSHORT default_char_set_id)
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
char_set_id = FLD.RDB$CHARACTER_SET_ID;
if ((char_set_id != default_char_set_id) || collation)
ISQL_get_character_sets (char_set_id, 0, false, false, true, char_sets);
if (char_set_id != default_char_set_id)
ISQL_get_character_sets(char_set_id, collation, false, true, false, true, char_sets);
if (char_sets[0])
isqlGlob.prints(char_sets);
// CVC: Someone deleted the code that checks intchar when handling collations

View File

@ -1441,7 +1441,8 @@ SSHORT ISQL_get_char_length(
}
void ISQL_get_character_sets(SSHORT char_set_id, SSHORT collation, bool collate_only,
void ISQL_get_character_sets(SSHORT char_set_id, SSHORT collation,
bool getCharset, bool getCollation,
bool not_null, bool quote, TEXT* string)
{
/**************************************
@ -1463,8 +1464,7 @@ void ISQL_get_character_sets(SSHORT char_set_id, SSHORT collation, bool collate_
if (!frontendTransaction())
return;
//if (collation) {
if (collation || collate_only)
if (getCollation)
{
FOR FIRST 1 COL IN RDB$COLLATIONS CROSS
CST IN RDB$CHARACTER_SETS WITH
@ -1497,12 +1497,12 @@ void ISQL_get_character_sets(SSHORT char_set_id, SSHORT collation, bool collate_
// Is specified collation the default collation for character set?
if (strcmp (CST.RDB$DEFAULT_COLLATE_NAME, COL.RDB$COLLATION_NAME) == 0)
{
if (!collate_only)
if (getCharset)
sprintf (string, " CHARACTER SET %s%s", charSetName, notNullStr);
}
else if (collate_only)
else if (!getCharset) // Only collation is requested
sprintf (string, "%s COLLATE %s", notNullStr, collateName);
else
else // Both
sprintf (string, " CHARACTER SET %s%s COLLATE %s",
charSetName, notNullStr, collateName);
END_FOR

View File

@ -41,7 +41,10 @@ void ISQL_exit_db();
//int ISQL_extract(TEXT*, int, FILE*, FILE*, FILE*);
int ISQL_frontend_command(TEXT*, FILE*, FILE*, FILE*);
bool ISQL_get_base_column_null_flag(const TEXT*, const SSHORT, const TEXT*);
void ISQL_get_character_sets(SSHORT, SSHORT, bool, bool, bool, TEXT*);
void ISQL_get_character_sets(
SSHORT char_set_id, SSHORT collation,
bool getCharset, bool getCollation,
bool not_null, bool quote, TEXT* string);
SSHORT ISQL_get_default_char_set_id();
void ISQL_get_default_source(const TEXT*, TEXT*, ISC_QUAD*);
SSHORT ISQL_get_field_length(const TEXT*);

View File

@ -86,7 +86,7 @@ enum commentMode {cmmShow, cmmExtract};
static void remove_delimited_double_quotes(TEXT*);
static void make_priv_string(USHORT, char*, bool);
static processing_state show_all_tables(SSHORT);
static void show_charsets(const SCHAR*, const SCHAR*, const bool, bool, bool, bool);
static void show_charsets(SSHORT char_set_id, SSHORT collation, bool show_charset, bool show_collation, bool doIndent, bool doNewLine);
static processing_state show_check(const SCHAR*);
static processing_state show_collations(const SCHAR*, SSHORT sys_flag, const char* msg = 0, bool compact = false);
static void show_comment(const char* objtype, char* packageName, char* name1, char* name2,
@ -2947,7 +2947,7 @@ static processing_state show_all_tables(SSHORT sys_flag)
}
static void show_charsets(const SCHAR* relation_name, const SCHAR* field_name,
static void show_charsets(SSHORT char_set_id, SSHORT collation,
bool show_charset, bool show_collation,
bool doIndent, bool doNewLine)
{
@ -2958,68 +2958,16 @@ static void show_charsets(const SCHAR* relation_name, const SCHAR* field_name,
**************************************
*
* Functional description
* Show character set and collations
* Show names of character set and collations
*
**************************************/
SSHORT collation = -1, char_set_id = -1;
const SSHORT default_char_set_id = ISQL_get_default_char_set_id();
// If there is a relation_name, this is a real column, look up collation
// in rdb$relation_fields
if (relation_name)
{
FOR RRF IN RDB$RELATION_FIELDS CROSS
FLD IN RDB$FIELDS
WITH RRF.RDB$FIELD_NAME EQ field_name AND
RRF.RDB$RELATION_NAME EQ relation_name AND
RRF.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME
char_set_id = 0;
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
char_set_id = FLD.RDB$CHARACTER_SET_ID;
collation = 0;
if (!RRF.RDB$COLLATION_ID.NULL)
collation = RRF.RDB$COLLATION_ID;
else if (!FLD.RDB$COLLATION_ID.NULL)
collation = FLD.RDB$COLLATION_ID;
END_FOR
ON_ERROR
#ifdef DEV_BUILD
fprintf(stderr, "show_charsets(%s %s) failed\n", relation_name, field_name);
#endif
END_ERROR;
}
else
{
FOR FLD IN RDB$FIELDS WITH
FLD.RDB$FIELD_NAME EQ field_name
char_set_id = 0;
collation = 0;
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
char_set_id = FLD.RDB$CHARACTER_SET_ID;
if (!FLD.RDB$COLLATION_ID.NULL)
collation = FLD.RDB$COLLATION_ID;
END_FOR
ON_ERROR
#ifdef DEV_BUILD
fprintf(stderr, "show_charsets(NULL %s) failed\n",
field_name);
#endif
END_ERROR;
}
TEXT char_sets[CHARSET_COLLATE_SIZE];
char_sets[0] = 0;
if ((char_set_id != default_char_set_id) || collation)
if ((char_set_id != default_char_set_id) || show_collation)
{
if (show_charset && !show_collation)
ISQL_get_character_sets(char_set_id, 0, false, false, false, char_sets);
else if (!show_charset && show_collation)
ISQL_get_character_sets(char_set_id, collation, true, false, false, char_sets);
else
ISQL_get_character_sets(char_set_id, collation, false, false, false, char_sets);
ISQL_get_character_sets(char_set_id, collation, show_charset, show_collation, false, false, char_sets);
}
if (char_sets[0])
{
@ -4094,11 +4042,19 @@ static processing_state show_domains(const SCHAR* domain_name)
}
// Show international character sets
SSHORT char_set_id = 0;
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
char_set_id = FLD.RDB$CHARACTER_SET_ID;
SSHORT collation = 0;
if (!FLD.RDB$COLLATION_ID.NULL)
collation = FLD.RDB$COLLATION_ID;
if (((FLD.RDB$FIELD_TYPE == blr_text ||
FLD.RDB$FIELD_TYPE == blr_varying) && FLD.RDB$FIELD_SUB_TYPE != fb_text_subtype_binary) ||
FLD.RDB$FIELD_TYPE == blr_blob)
{
show_charsets(NULL, FLD.RDB$FIELD_NAME, true, false, false, false);
show_charsets(char_set_id, collation, true, false, false, false);
}
if (FLD.RDB$NULL_FLAG != 1) {
@ -4130,7 +4086,7 @@ static processing_state show_domains(const SCHAR* domain_name)
FLD.RDB$FIELD_TYPE == blr_varying ||
FLD.RDB$FIELD_TYPE == blr_blob)
{
show_charsets(NULL, FLD.RDB$FIELD_NAME, false, true, true, true);
show_charsets(char_set_id, collation, false, true, true, true);
}
END_FOR
@ -4608,10 +4564,9 @@ static processing_state show_func(const MetaString& package, const MetaString& f
TEXT charset_collation[CHARSET_COLLATE_SIZE];
charset_collation[0] = 0;
if ((charset != default_charset) || collation)
if (charset != default_charset)
{
ISQL_get_character_sets(charset, collation, false, false, false,
charset_collation);
ISQL_get_character_sets(charset, collation, true, true, false, false, charset_collation);
}
if (charset_collation[0])
@ -5514,9 +5469,9 @@ static processing_state show_proc(const SCHAR* procname, bool quoted, bool sys,
TEXT charset_collation[CHARSET_COLLATE_SIZE];
charset_collation[0] = 0;
if ((charset != default_charset) || collation)
if (charset != default_charset)
{
ISQL_get_character_sets(charset, collation, false, false, false,
ISQL_get_character_sets(charset, collation, true, true, false, false,
charset_collation);
}
@ -6171,13 +6126,23 @@ static processing_state show_table(const SCHAR* relation_name, bool isView)
return ps_ERR;
}
SSHORT char_set_id = 0;
if (!FLD.RDB$CHARACTER_SET_ID.NULL)
char_set_id = FLD.RDB$CHARACTER_SET_ID;
SSHORT collation = 0;
if (!RFR.RDB$COLLATION_ID.NULL)
collation = RFR.RDB$COLLATION_ID;
else if (!FLD.RDB$COLLATION_ID.NULL)
collation = FLD.RDB$COLLATION_ID;
if ((FLD.RDB$FIELD_TYPE == blr_text) || (FLD.RDB$FIELD_TYPE == blr_varying)) {
isqlGlob.printf("(%d)", ISQL_get_field_length(FLD.RDB$FIELD_NAME));
if (FLD.RDB$FIELD_SUB_TYPE != fb_text_subtype_binary)
{
// Show international character sets and collations
show_charsets(relation_name, RFR.RDB$FIELD_NAME, true, false, false, false);
show_charsets(char_set_id, collation, true, false, false, false);
}
}
@ -6196,7 +6161,7 @@ static processing_state show_table(const SCHAR* relation_name, bool isView)
// Show international character sets and collations
show_charsets(relation_name, RFR.RDB$FIELD_NAME, true, false, false, false);
show_charsets(char_set_id, collation, true, false, false, false);
}
if (!FLD.RDB$COMPUTED_BLR.NULL)
@ -6245,7 +6210,7 @@ static processing_state show_table(const SCHAR* relation_name, bool isView)
if ((FLD.RDB$FIELD_TYPE == blr_text) || (FLD.RDB$FIELD_TYPE == blr_varying) ||
(FLD.RDB$FIELD_TYPE == blr_blob))
{
show_charsets(relation_name, RFR.RDB$FIELD_NAME, false, true, true, true);
show_charsets(char_set_id, collation, false, true, true, true);
}
END_FOR