8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 04:43: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:
Adriano dos Santos Fernandes 2021-04-01 14:01:27 -03:00
parent 0c278bd29f
commit 1b646a3869
5 changed files with 164 additions and 17 deletions

View File

@ -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))

View File

@ -575,7 +575,7 @@ static bool M_Transaction()
{ {
if (DB && !M__trans && setValues.KeepTranParams) if (DB && !M__trans && setValues.KeepTranParams)
{ {
M__trans = DB->execute(fbStatus, NULL, M__trans = DB->execute(fbStatus, NULL,
TranParams->length(), TranParams->c_str(), TranParams->length(), TranParams->c_str(),
isqlGlob.SQL_dialect, NULL, NULL, NULL, NULL); isqlGlob.SQL_dialect, NULL, NULL, NULL, NULL);
@ -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);
} }

View File

@ -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

View File

@ -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);
} }

View File

@ -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);