mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 04:03: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)
|
||||
{
|
||||
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)
|
||||
@ -801,7 +801,7 @@ static void get_procedure_args(const char* proc_name)
|
||||
if (!prm_default_source_null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -2384,7 +2384,7 @@ static void list_domains(SSHORT default_char_set_id)
|
||||
if (!FLD.RDB$DEFAULT_SOURCE.NULL)
|
||||
{
|
||||
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().
|
||||
if (FLD.RDB$NULL_FLAG == 1)
|
||||
@ -3270,7 +3270,7 @@ static void list_indexes()
|
||||
{
|
||||
isqlGlob.printf(" COMPUTED BY ");
|
||||
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);
|
||||
}
|
||||
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,
|
||||
TEXT* field_name,
|
||||
ISC_QUAD* blob_id)
|
||||
@ -1951,6 +2068,7 @@ void ISQL_print_validation(FILE* fp,
|
||||
bool issql = false;
|
||||
bool firsttime = true;
|
||||
TEXT buffer[BUFFER_LENGTH512];
|
||||
Firebird::string fullText;
|
||||
|
||||
do
|
||||
{
|
||||
@ -1988,6 +2106,7 @@ void ISQL_print_validation(FILE* fp,
|
||||
}
|
||||
|
||||
IUTILS_printf(fp, buffer);
|
||||
fullText += buffer;
|
||||
} while (true);
|
||||
|
||||
// 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);
|
||||
|
||||
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*);
|
||||
processing_state ISQL_print_item_blob(FILE*, const IsqlVar*, Firebird::ITransaction*, int subtype);
|
||||
processing_state ISQL_fill_var(IsqlVar*, Firebird::IMessageMetadata*, unsigned, UCHAR*);
|
||||
bool ISQL_statement_ends_in_comment(const char* statement);
|
||||
|
||||
#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))
|
||||
return;
|
||||
|
||||
string fullText;
|
||||
SCHAR buffer[BUFFER_LENGTH512];
|
||||
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')
|
||||
fputc('\r', fp);
|
||||
{
|
||||
fputc('\r', fp);
|
||||
if (avoid_end_in_single_line_comment)
|
||||
fullText += "\r";
|
||||
}
|
||||
|
||||
if (escape_squote)
|
||||
{
|
||||
for (const UCHAR* p = (UCHAR*) buffer; *p; ++p)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
IUTILS_printf(fp, buffer);
|
||||
if (avoid_end_in_single_line_comment)
|
||||
fullText += buffer;
|
||||
}
|
||||
}
|
||||
|
||||
if (endedWithCr)
|
||||
fputc('\r', fp);
|
||||
{
|
||||
fputc('\r', fp);
|
||||
if (avoid_end_in_single_line_comment)
|
||||
fullText += "\r";
|
||||
}
|
||||
|
||||
if (fbStatus->getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
ISQL_errmsg(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);
|
||||
void SHOW_grant_roles (const SCHAR*, 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**);
|
||||
void SHOW_read_owner();
|
||||
const Firebird::string SHOW_trigger_action(SINT64);
|
||||
|
Loading…
Reference in New Issue
Block a user