mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 07:23:03 +01:00
Fixed CORE-6527 - Regression: inline comment of SP parameter with closing
parenthesis leads to incorrect SQL when trying to extract metadata.
This commit is contained in:
parent
0c278bd29f
commit
1b646a3869
@ -494,7 +494,7 @@ int EXTRACT_list_table(const SCHAR* relation_name,
|
|||||||
if (!RFR.RDB$DEFAULT_SOURCE.NULL)
|
if (!RFR.RDB$DEFAULT_SOURCE.NULL)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob (isqlGlob.Out, &RFR.RDB$DEFAULT_SOURCE);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &RFR.RDB$DEFAULT_SOURCE, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RFR.RDB$GENERATOR_NAME.NULL)
|
if (!RFR.RDB$GENERATOR_NAME.NULL)
|
||||||
@ -801,7 +801,7 @@ static void get_procedure_args(const char* proc_name)
|
|||||||
if (!prm_default_source_null)
|
if (!prm_default_source_null)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -852,12 +852,12 @@ static void get_procedure_args(const char* proc_name)
|
|||||||
if (!prm_default_source_null)
|
if (!prm_default_source_null)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source, false, true);
|
||||||
}
|
}
|
||||||
else if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
else if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob(isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1020,7 +1020,7 @@ static void get_function_args_ods12(const char* func_name, USHORT out_arg)
|
|||||||
if (!prm_default_source_null)
|
if (!prm_default_source_null)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1072,12 +1072,12 @@ static void get_function_args_ods12(const char* func_name, USHORT out_arg)
|
|||||||
if (!prm_default_source_null)
|
if (!prm_default_source_null)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &prm_default_source, false, true);
|
||||||
}
|
}
|
||||||
else if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
else if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
||||||
{
|
{
|
||||||
isqlGlob.printf(" ");
|
isqlGlob.printf(" ");
|
||||||
SHOW_print_metadata_text_blob(isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2262,7 +2262,7 @@ static void list_domain_table(const SCHAR* table_name, SSHORT default_char_set_i
|
|||||||
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
||||||
{
|
{
|
||||||
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
||||||
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE, false, true);
|
||||||
}
|
}
|
||||||
if (!FLD.RDB$VALIDATION_SOURCE.NULL)
|
if (!FLD.RDB$VALIDATION_SOURCE.NULL)
|
||||||
{
|
{
|
||||||
@ -2384,7 +2384,7 @@ static void list_domains(SSHORT default_char_set_id)
|
|||||||
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
||||||
{
|
{
|
||||||
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
isqlGlob.printf("%s%s ", NEWLINE, TAB_AS_SPACES);
|
||||||
SHOW_print_metadata_text_blob (isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &FLD.RDB$DEFAULT_SOURCE, false, true);
|
||||||
}
|
}
|
||||||
// Validation moved to listDomainConstraints().
|
// Validation moved to listDomainConstraints().
|
||||||
if (FLD.RDB$NULL_FLAG == 1)
|
if (FLD.RDB$NULL_FLAG == 1)
|
||||||
@ -3270,7 +3270,7 @@ static void list_indexes()
|
|||||||
{
|
{
|
||||||
isqlGlob.printf(" COMPUTED BY ");
|
isqlGlob.printf(" COMPUTED BY ");
|
||||||
if (!IDX.RDB$EXPRESSION_SOURCE.NULL)
|
if (!IDX.RDB$EXPRESSION_SOURCE.NULL)
|
||||||
SHOW_print_metadata_text_blob (isqlGlob.Out, &IDX.RDB$EXPRESSION_SOURCE);
|
SHOW_print_metadata_text_blob(isqlGlob.Out, &IDX.RDB$EXPRESSION_SOURCE, false, true);
|
||||||
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
isqlGlob.printf("%s%s", isqlGlob.global_Term, NEWLINE);
|
||||||
}
|
}
|
||||||
else if (ISQL_get_index_segments (collist, sizeof(collist), IDX.RDB$INDEX_NAME, true))
|
else if (ISQL_get_index_segments (collist, sizeof(collist), IDX.RDB$INDEX_NAME, true))
|
||||||
|
@ -1390,6 +1390,123 @@ processing_state ISQL_fill_var(IsqlVar* var,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if statement ends with single-line comment.
|
||||||
|
bool ISQL_statement_ends_in_comment(const char* statement)
|
||||||
|
{
|
||||||
|
const char* const statementStart = statement;
|
||||||
|
const char* commentStart = NULL;
|
||||||
|
const char* commentEnd = NULL;
|
||||||
|
const char* altQuoteStart = NULL;
|
||||||
|
char altQuoteChar = '\0';
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
normal,
|
||||||
|
in_single_line_comment,
|
||||||
|
in_block_comment,
|
||||||
|
in_single_quoted_string,
|
||||||
|
in_double_quoted_string
|
||||||
|
} state = normal;
|
||||||
|
|
||||||
|
while (char c = *statement++)
|
||||||
|
{
|
||||||
|
char lastChar = statement - 1 == statementStart ? '\0' : statement[-2];
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '\n':
|
||||||
|
if (state == in_single_line_comment)
|
||||||
|
state = normal;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
// Could this the be start of a single-line comment.
|
||||||
|
if (state == normal && lastChar == '-')
|
||||||
|
state = in_single_line_comment;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '*':
|
||||||
|
// Could this the be start of a comment. We can only look back, not forward.
|
||||||
|
// Ignore possibilities of a comment beginning inside quoted strings.
|
||||||
|
if (state == normal && lastChar == '/' && statement - commentEnd > 3)
|
||||||
|
{
|
||||||
|
state = in_block_comment;
|
||||||
|
commentStart = statement - 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '/':
|
||||||
|
// Perhaps this is the end of a comment.
|
||||||
|
// Ignore possibilities of a comment ending inside quoted strings.
|
||||||
|
// Ignore things like /*/ since it isn't a block comment; only the start of it. Or end.
|
||||||
|
if (state == in_block_comment && lastChar == '*' && statement - commentStart > 3)
|
||||||
|
{
|
||||||
|
state = normal;
|
||||||
|
commentEnd = statement - 2; // mark start of non-comment to track this: /**/*
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SINGLE_QUOTE:
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case normal:
|
||||||
|
if (lastChar == 'q' || lastChar == 'Q')
|
||||||
|
{
|
||||||
|
altQuoteStart = statement - 2;
|
||||||
|
|
||||||
|
if (!(altQuoteChar = *statement++))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (altQuoteChar)
|
||||||
|
{
|
||||||
|
case '{':
|
||||||
|
altQuoteChar = '}';
|
||||||
|
break;
|
||||||
|
case '(':
|
||||||
|
altQuoteChar = ')';
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
altQuoteChar = ']';
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
altQuoteChar = '>';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
altQuoteChar = '\0';
|
||||||
|
|
||||||
|
state = in_single_quoted_string;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case in_single_quoted_string:
|
||||||
|
if (!altQuoteChar || lastChar == altQuoteChar)
|
||||||
|
state = normal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DBL_QUOTE:
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case normal:
|
||||||
|
state = in_double_quoted_string;
|
||||||
|
break;
|
||||||
|
case in_double_quoted_string:
|
||||||
|
state = normal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state == in_single_line_comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ISQL_get_default_source(const TEXT* rel_name,
|
void ISQL_get_default_source(const TEXT* rel_name,
|
||||||
TEXT* field_name,
|
TEXT* field_name,
|
||||||
ISC_QUAD* blob_id)
|
ISC_QUAD* blob_id)
|
||||||
@ -1951,6 +2068,7 @@ void ISQL_print_validation(FILE* fp,
|
|||||||
bool issql = false;
|
bool issql = false;
|
||||||
bool firsttime = true;
|
bool firsttime = true;
|
||||||
TEXT buffer[BUFFER_LENGTH512];
|
TEXT buffer[BUFFER_LENGTH512];
|
||||||
|
Firebird::string fullText;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -1988,6 +2106,7 @@ void ISQL_print_validation(FILE* fp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
IUTILS_printf(fp, buffer);
|
IUTILS_printf(fp, buffer);
|
||||||
|
fullText += buffer;
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
// CVC: If firsttime == true, then it didn't write the "/*" or the "(".
|
// CVC: If firsttime == true, then it didn't write the "/*" or the "(".
|
||||||
@ -1998,6 +2117,9 @@ void ISQL_print_validation(FILE* fp,
|
|||||||
ISQL_errmsg(fbStatus);
|
ISQL_errmsg(fbStatus);
|
||||||
|
|
||||||
blob->close(fbStatus);
|
blob->close(fbStatus);
|
||||||
|
|
||||||
|
if (ISQL_statement_ends_in_comment(fullText.c_str()))
|
||||||
|
fputc('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,5 +66,6 @@ void ISQL_ri_action_print(const TEXT*, const TEXT*, bool);
|
|||||||
//void ISQL_win_err(const char*);
|
//void ISQL_win_err(const char*);
|
||||||
processing_state ISQL_print_item_blob(FILE*, const IsqlVar*, Firebird::ITransaction*, int subtype);
|
processing_state ISQL_print_item_blob(FILE*, const IsqlVar*, Firebird::ITransaction*, int subtype);
|
||||||
processing_state ISQL_fill_var(IsqlVar*, Firebird::IMessageMetadata*, unsigned, UCHAR*);
|
processing_state ISQL_fill_var(IsqlVar*, Firebird::IMessageMetadata*, unsigned, UCHAR*);
|
||||||
|
bool ISQL_statement_ends_in_comment(const char* statement);
|
||||||
|
|
||||||
#endif // ISQL_ISQL_PROTO_H
|
#endif // ISQL_ISQL_PROTO_H
|
||||||
|
@ -1853,7 +1853,7 @@ void SHOW_grant_roles2 (const SCHAR* terminator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHOW_print_metadata_text_blob(FILE* fp, ISC_QUAD* blobid, bool escape_squote)
|
void SHOW_print_metadata_text_blob(FILE* fp, ISC_QUAD* blobid, bool escape_squote, bool avoid_end_in_single_line_comment)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
*
|
*
|
||||||
@ -1876,6 +1876,7 @@ void SHOW_print_metadata_text_blob(FILE* fp, ISC_QUAD* blobid, bool escape_squot
|
|||||||
if (ISQL_errmsg(fbStatus))
|
if (ISQL_errmsg(fbStatus))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
string fullText;
|
||||||
SCHAR buffer[BUFFER_LENGTH512];
|
SCHAR buffer[BUFFER_LENGTH512];
|
||||||
bool endedWithCr = false;
|
bool endedWithCr = false;
|
||||||
|
|
||||||
@ -1907,29 +1908,51 @@ void SHOW_print_metadata_text_blob(FILE* fp, ISC_QUAD* blobid, bool escape_squot
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (prevEndedWithCr && buffer[0] != '\n')
|
if (prevEndedWithCr && buffer[0] != '\n')
|
||||||
fputc('\r', fp);
|
{
|
||||||
|
fputc('\r', fp);
|
||||||
|
if (avoid_end_in_single_line_comment)
|
||||||
|
fullText += "\r";
|
||||||
|
}
|
||||||
|
|
||||||
if (escape_squote)
|
if (escape_squote)
|
||||||
{
|
{
|
||||||
for (const UCHAR* p = (UCHAR*) buffer; *p; ++p)
|
for (const UCHAR* p = (UCHAR*) buffer; *p; ++p)
|
||||||
{
|
{
|
||||||
if (*p == SINGLE_QUOTE)
|
if (*p == SINGLE_QUOTE)
|
||||||
fputc(*p, fp);
|
{
|
||||||
fputc(*p, fp);
|
fputc(*p, fp);
|
||||||
|
if (avoid_end_in_single_line_comment)
|
||||||
|
fullText += *p;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc(*p, fp);
|
||||||
|
if (avoid_end_in_single_line_comment)
|
||||||
|
fullText += *p;
|
||||||
}
|
}
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
IUTILS_printf(fp, buffer);
|
IUTILS_printf(fp, buffer);
|
||||||
|
if (avoid_end_in_single_line_comment)
|
||||||
|
fullText += buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endedWithCr)
|
if (endedWithCr)
|
||||||
fputc('\r', fp);
|
{
|
||||||
|
fputc('\r', fp);
|
||||||
|
if (avoid_end_in_single_line_comment)
|
||||||
|
fullText += "\r";
|
||||||
|
}
|
||||||
|
|
||||||
if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
|
if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||||
ISQL_errmsg(fbStatus);
|
ISQL_errmsg(fbStatus);
|
||||||
|
|
||||||
blob->close(fbStatus);
|
blob->close(fbStatus);
|
||||||
|
|
||||||
|
if (avoid_end_in_single_line_comment && ISQL_statement_ends_in_comment(fullText.c_str()))
|
||||||
|
fputc('\n', fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +33,8 @@ processing_state SHOW_grants (const SCHAR*, const SCHAR*, USHORT);
|
|||||||
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, USHORT, const TEXT*, bool);
|
processing_state SHOW_grants2 (const SCHAR*, const SCHAR*, USHORT, const TEXT*, bool);
|
||||||
void SHOW_grant_roles (const SCHAR*, bool*);
|
void SHOW_grant_roles (const SCHAR*, bool*);
|
||||||
void SHOW_grant_roles2 (const SCHAR*, bool*, const TEXT*, bool);
|
void SHOW_grant_roles2 (const SCHAR*, bool*, const TEXT*, bool);
|
||||||
void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false);
|
void SHOW_print_metadata_text_blob(FILE*, ISC_QUAD*, bool escape_squote = false,
|
||||||
|
bool avoid_end_in_single_line_comment = false);
|
||||||
processing_state SHOW_metadata(const SCHAR* const*, SCHAR**);
|
processing_state SHOW_metadata(const SCHAR* const*, SCHAR**);
|
||||||
void SHOW_read_owner();
|
void SHOW_read_owner();
|
||||||
const Firebird::string SHOW_trigger_action(SINT64);
|
const Firebird::string SHOW_trigger_action(SINT64);
|
||||||
|
Loading…
Reference in New Issue
Block a user