-
-
Notifications
You must be signed in to change notification settings - Fork 234
Extract external routines in one pass #8054
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,6 +94,8 @@ static void list_package_headers(); | |
static void list_procedure_bodies(SSHORT default_char_set_id); | ||
static void list_procedure_headers(SSHORT default_char_set_id); | ||
static void list_views(); | ||
static void list_external_procedures(SSHORT default_char_set_id); | ||
static void list_external_functions(SSHORT default_char_set_id); | ||
|
||
static const char* const Procterm = "^"; // TXNN: script use only | ||
|
||
|
@@ -179,6 +181,8 @@ int EXTRACT_ddl(LegacyTables flag, const SCHAR* tabname) | |
list_domains(default_char_set_id); | ||
list_all_tables(flag, default_char_set_id); | ||
list_functions_legacy(); | ||
list_external_functions(default_char_set_id); | ||
list_external_procedures(default_char_set_id); | ||
list_functions_ods12_headers(default_char_set_id); | ||
list_procedure_headers(default_char_set_id); | ||
list_package_headers(); | ||
|
@@ -1509,6 +1513,8 @@ static void list_procedure_headers(SSHORT default_char_set_id) | |
FOR PRC IN RDB$PROCEDURES | ||
WITH (PRC.RDB$SYSTEM_FLAG NE 1 OR PRC.RDB$SYSTEM_FLAG MISSING) | ||
AND PRC.RDB$PACKAGE_NAME MISSING | ||
AND PRC.RDB$ENGINE_NAME MISSING | ||
AND PRC.RDB$ENTRYPOINT MISSING | ||
SORTED BY PRC.RDB$PROCEDURE_NAME | ||
if (header) | ||
{ | ||
|
@@ -1573,6 +1579,8 @@ static void list_procedure_bodies(SSHORT default_char_set_id) | |
FOR PRC IN RDB$PROCEDURES | ||
WITH (PRC.RDB$SYSTEM_FLAG NE 1 OR PRC.RDB$SYSTEM_FLAG MISSING) | ||
AND PRC.RDB$PACKAGE_NAME MISSING | ||
AND PRC.RDB$ENGINE_NAME MISSING | ||
AND PRC.RDB$ENTRYPOINT MISSING | ||
SORTED BY PRC.RDB$PROCEDURE_NAME | ||
if (header) | ||
{ | ||
|
@@ -1593,32 +1601,13 @@ static void list_procedure_bodies(SSHORT default_char_set_id) | |
|
||
// Print the procedure body | ||
|
||
if (!PRC.RDB$ENTRYPOINT.NULL) | ||
{ | ||
fb_utils::exact_name(PRC.RDB$ENTRYPOINT); | ||
IUTILS_copy_SQL_id(PRC.RDB$ENTRYPOINT, SQL_identifier2, SINGLE_QUOTE); | ||
isqlGlob.printf("EXTERNAL NAME %s%s", SQL_identifier2, NEWLINE); | ||
} | ||
|
||
if (!PRC.RDB$SQL_SECURITY.NULL) | ||
{ | ||
const char* ss = PRC.RDB$SQL_SECURITY ? "SQL SECURITY DEFINER" : "SQL SECURITY INVOKER"; | ||
isqlGlob.printf("%s%s", ss, NEWLINE); | ||
} | ||
|
||
if (!PRC.RDB$ENGINE_NAME.NULL) | ||
{ | ||
fb_utils::exact_name(PRC.RDB$ENGINE_NAME); | ||
isqlGlob.printf("ENGINE %s", PRC.RDB$ENGINE_NAME); | ||
|
||
if (!PRC.RDB$PROCEDURE_SOURCE.NULL) | ||
{ | ||
isqlGlob.printf("%sAS '", NEWLINE); | ||
SHOW_print_metadata_text_blob(isqlGlob.Out, &PRC.RDB$PROCEDURE_SOURCE, true); | ||
isqlGlob.printf("'%s", NEWLINE); | ||
} | ||
} | ||
else if (!PRC.RDB$PROCEDURE_SOURCE.NULL) | ||
if (!PRC.RDB$PROCEDURE_SOURCE.NULL) | ||
{ | ||
isqlGlob.printf("AS %s", NEWLINE); | ||
SHOW_print_metadata_text_blob(isqlGlob.Out, &PRC.RDB$PROCEDURE_SOURCE); | ||
|
@@ -3109,6 +3098,8 @@ static void list_functions_ods12_headers(SSHORT default_char_set_id) | |
WITH (FUN.RDB$SYSTEM_FLAG NE 1 OR FUN.RDB$SYSTEM_FLAG MISSING) | ||
AND FUN.RDB$PACKAGE_NAME MISSING | ||
AND FUN.RDB$MODULE_NAME MISSING | ||
AND FUN.RDB$ENGINE_NAME MISSING | ||
AND FUN.RDB$ENTRYPOINT MISSING | ||
SORTED BY FUN.RDB$FUNCTION_NAME | ||
|
||
if (header) | ||
|
@@ -3161,6 +3152,8 @@ static void list_functions_ods12_bodies(SSHORT default_char_set_id) | |
WITH (FUN.RDB$SYSTEM_FLAG NE 1 OR FUN.RDB$SYSTEM_FLAG MISSING) | ||
AND FUN.RDB$PACKAGE_NAME MISSING | ||
AND FUN.RDB$MODULE_NAME MISSING | ||
AND FUN.RDB$ENGINE_NAME MISSING | ||
AND FUN.RDB$ENTRYPOINT MISSING | ||
SORTED BY FUN.RDB$FUNCTION_NAME | ||
if (header) | ||
{ | ||
|
@@ -3184,32 +3177,13 @@ static void list_functions_ods12_bodies(SSHORT default_char_set_id) | |
|
||
// Print the function body | ||
|
||
if (!FUN.RDB$ENTRYPOINT.NULL) | ||
{ | ||
fb_utils::exact_name(FUN.RDB$ENTRYPOINT); | ||
IUTILS_copy_SQL_id(FUN.RDB$ENTRYPOINT, SQL_identifier2, SINGLE_QUOTE); | ||
isqlGlob.printf("EXTERNAL NAME %s%s", SQL_identifier2, NEWLINE); | ||
} | ||
|
||
if (!FUN.RDB$SQL_SECURITY.NULL) | ||
{ | ||
const char* ss = FUN.RDB$SQL_SECURITY ? "SQL SECURITY DEFINER" : "SQL SECURITY INVOKER"; | ||
isqlGlob.printf("%s%s", ss, NEWLINE); | ||
} | ||
|
||
if (!FUN.RDB$ENGINE_NAME.NULL) | ||
{ | ||
fb_utils::exact_name(FUN.RDB$ENGINE_NAME); | ||
isqlGlob.printf("ENGINE %s", FUN.RDB$ENGINE_NAME); | ||
|
||
if (!FUN.RDB$FUNCTION_SOURCE.NULL) | ||
{ | ||
isqlGlob.printf("%sAS '", NEWLINE); | ||
SHOW_print_metadata_text_blob(isqlGlob.Out, &FUN.RDB$FUNCTION_SOURCE, true); | ||
isqlGlob.printf("'%s", NEWLINE); | ||
} | ||
} | ||
else if (!FUN.RDB$FUNCTION_SOURCE.NULL) | ||
if (!FUN.RDB$FUNCTION_SOURCE.NULL) | ||
{ | ||
isqlGlob.printf("AS %s", NEWLINE); | ||
SHOW_print_metadata_text_blob(isqlGlob.Out, &FUN.RDB$FUNCTION_SOURCE); | ||
|
@@ -3594,3 +3568,172 @@ static void list_views() | |
return; | ||
END_ERROR; | ||
} | ||
|
||
static void list_external_procedures(SSHORT default_char_set_id) | ||
{ | ||
/************************************** | ||
* | ||
* l i s t _ e x t e r n a l _ p r o c e d u r e s | ||
* | ||
************************************** | ||
* | ||
* Functional description | ||
* Create all external procedures declarations. | ||
* | ||
**************************************/ | ||
|
||
fb_assert(isqlGlob.major_ods >= ODS_VERSION12); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How this is supposed to work with pre ODS13 databases ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Current ISQL (FB 3-4-5) cannot extract procedures/functions from pre-ODS12 databases, so nothing really changed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both so, what happens in case of pre-ODS13 DB ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error "field does not exist". You may find the same assert in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strange logic, as for me - use assert and runtime error instead of condition and correct handling of old ODS. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC, it was discussed in fb-devel and we agreed to simplify the code this way, but it was ages ago... |
||
|
||
bool header = true; | ||
static const char* const create_procedure = "CREATE OR ALTER PROCEDURE %s "; | ||
|
||
// Create the external procedures with their parameters | ||
TEXT msg[MSG_LENGTH]; | ||
|
||
FOR PRC IN RDB$PROCEDURES | ||
WITH (PRC.RDB$SYSTEM_FLAG NE 1 OR PRC.RDB$SYSTEM_FLAG MISSING) | ||
AND PRC.RDB$PACKAGE_NAME MISSING | ||
AND PRC.RDB$ENGINE_NAME NOT MISSING | ||
AND PRC.RDB$ENTRYPOINT NOT MISSING | ||
SORTED BY PRC.RDB$PROCEDURE_NAME | ||
if (header) | ||
{ | ||
isqlGlob.printf("%sCOMMIT WORK%s%s", NEWLINE, isqlGlob.global_Term, NEWLINE); | ||
isqlGlob.printf("SET AUTODDL OFF%s%s", isqlGlob.global_Term, NEWLINE); | ||
isqlGlob.printf("SET TERM %s %s%s", Procterm, isqlGlob.global_Term, NEWLINE); | ||
isqlGlob.printf("%s/* %s */%s", NEWLINE, "External procedures", NEWLINE); | ||
header = false; | ||
} | ||
fb_utils::exact_name(PRC.RDB$PROCEDURE_NAME); | ||
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) | ||
{ | ||
IUTILS_copy_SQL_id (PRC.RDB$PROCEDURE_NAME, SQL_identifier, DBL_QUOTE); | ||
isqlGlob.printf(create_procedure, SQL_identifier); | ||
} | ||
else | ||
{ | ||
isqlGlob.printf(create_procedure, PRC.RDB$PROCEDURE_NAME); | ||
} | ||
|
||
get_procedure_args(PRC.RDB$PROCEDURE_NAME, default_char_set_id); | ||
|
||
fb_utils::exact_name(PRC.RDB$ENTRYPOINT); | ||
IUTILS_copy_SQL_id(PRC.RDB$ENTRYPOINT, SQL_identifier2, SINGLE_QUOTE); | ||
isqlGlob.printf("EXTERNAL NAME %s%s", SQL_identifier2, NEWLINE); | ||
|
||
if (!PRC.RDB$SQL_SECURITY.NULL) | ||
{ | ||
const char* ss = PRC.RDB$SQL_SECURITY ? "SQL SECURITY DEFINER" : "SQL SECURITY INVOKER"; | ||
isqlGlob.printf("%s%s", ss, NEWLINE); | ||
} | ||
|
||
fb_utils::exact_name(PRC.RDB$ENGINE_NAME); | ||
isqlGlob.printf("ENGINE %s", PRC.RDB$ENGINE_NAME); | ||
|
||
if (!PRC.RDB$PROCEDURE_SOURCE.NULL) | ||
{ | ||
isqlGlob.printf("%sAS '", NEWLINE); | ||
SHOW_print_metadata_text_blob(isqlGlob.Out, &PRC.RDB$PROCEDURE_SOURCE, true); | ||
isqlGlob.printf("'%s", NEWLINE); | ||
} | ||
|
||
isqlGlob.printf(" %s%s", Procterm, NEWLINE); | ||
|
||
END_FOR | ||
ON_ERROR | ||
IUTILS_msg_get(GEN_ERR, msg, SafeArg() << isc_sqlcode(fbStatus->getErrors())); | ||
STDERROUT(msg); // Statement failed, SQLCODE = %d\n\n | ||
ISQL_errmsg(fbStatus); | ||
return; | ||
END_ERROR; | ||
|
||
// Only reset the terminators if there were procedures to print | ||
if (!header) | ||
print_proc_suffix(obj_procedure); | ||
} | ||
|
||
static void list_external_functions(SSHORT default_char_set_id) | ||
{ | ||
/************************************** | ||
* | ||
* l i s t _ e x t e r n a l _ f u n c t i o n s | ||
* | ||
************************************** | ||
* | ||
* Functional description | ||
* Create all external functions declarations. | ||
* | ||
**************************************/ | ||
|
||
fb_assert(isqlGlob.major_ods >= ODS_VERSION12); | ||
|
||
bool header = true; | ||
static const char* const create_function = "CREATE OR ALTER FUNCTION %s "; | ||
|
||
// Create the external functions with their parameters | ||
TEXT msg[MSG_LENGTH]; | ||
|
||
FOR FUN IN RDB$FUNCTIONS | ||
WITH (FUN.RDB$SYSTEM_FLAG NE 1 OR FUN.RDB$SYSTEM_FLAG MISSING) | ||
AND FUN.RDB$PACKAGE_NAME MISSING | ||
AND FUN.RDB$MODULE_NAME MISSING | ||
AND FUN.RDB$ENGINE_NAME NOT MISSING | ||
AND FUN.RDB$ENTRYPOINT NOT MISSING | ||
SORTED BY FUN.RDB$FUNCTION_NAME | ||
|
||
if (header) | ||
{ | ||
isqlGlob.printf("%sCOMMIT WORK%s%s", NEWLINE, isqlGlob.global_Term, NEWLINE); | ||
isqlGlob.printf("SET AUTODDL OFF%s%s", isqlGlob.global_Term, NEWLINE); | ||
isqlGlob.printf("SET TERM %s %s%s", Procterm, isqlGlob.global_Term, NEWLINE); | ||
isqlGlob.printf("%s/* %s */%s", NEWLINE, "External functions", NEWLINE); | ||
header = false; | ||
} | ||
|
||
fb_utils::exact_name(FUN.RDB$FUNCTION_NAME); | ||
if (isqlGlob.db_SQL_dialect > SQL_DIALECT_V6_TRANSITION) | ||
{ | ||
IUTILS_copy_SQL_id(FUN.RDB$FUNCTION_NAME, SQL_identifier, DBL_QUOTE); | ||
isqlGlob.printf(create_function, SQL_identifier); | ||
} | ||
else | ||
{ | ||
isqlGlob.printf(create_function, FUN.RDB$FUNCTION_NAME); | ||
} | ||
|
||
get_function_args_ods12(FUN.RDB$FUNCTION_NAME, FUN.RDB$RETURN_ARGUMENT, default_char_set_id); | ||
|
||
fb_utils::exact_name(FUN.RDB$ENTRYPOINT); | ||
IUTILS_copy_SQL_id(FUN.RDB$ENTRYPOINT, SQL_identifier2, SINGLE_QUOTE); | ||
isqlGlob.printf("EXTERNAL NAME %s%s", SQL_identifier2, NEWLINE); | ||
|
||
if (!FUN.RDB$SQL_SECURITY.NULL) | ||
{ | ||
const char* ss = FUN.RDB$SQL_SECURITY ? "SQL SECURITY DEFINER" : "SQL SECURITY INVOKER"; | ||
isqlGlob.printf("%s%s", ss, NEWLINE); | ||
} | ||
|
||
fb_utils::exact_name(FUN.RDB$ENGINE_NAME); | ||
isqlGlob.printf("ENGINE %s", FUN.RDB$ENGINE_NAME); | ||
|
||
if (!FUN.RDB$FUNCTION_SOURCE.NULL) | ||
{ | ||
isqlGlob.printf("%sAS '", NEWLINE); | ||
SHOW_print_metadata_text_blob(isqlGlob.Out, &FUN.RDB$FUNCTION_SOURCE, true); | ||
isqlGlob.printf("'%s", NEWLINE); | ||
} | ||
|
||
isqlGlob.printf(" %s%s", Procterm, NEWLINE); | ||
|
||
END_FOR | ||
ON_ERROR | ||
IUTILS_msg_get(GEN_ERR, msg, SafeArg() << isc_sqlcode(fbStatus->getErrors())); | ||
STDERROUT(msg); // Statement failed, SQLCODE = %d\n\n | ||
ISQL_errmsg(fbStatus); | ||
return; | ||
END_ERROR; | ||
|
||
// Only reset the terminators if there were functions to print | ||
if (!header) | ||
print_proc_suffix(obj_udf); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that procedure without output parameters cannot be selectable?
select count(*) from anyUDR()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This causes
SQL error code = -84; procedure TEST_UDR does not return any values
. Even if the procedure hasprc_selectable
type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This solves a completely different problem. #7699
As for creating external procedures and functions in one-pass, I agree with @asfernandes. This is not necessary and can even be harmful in some cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sim1984 yes, this is exactly the bug we were fixing. I suggested a single pass extraction as an extension to the original patch.