8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 01: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:
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)
{
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))

View File

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

View File

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

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

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