diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c index a29f530327..35d94711d5 100644 --- a/src/interfaces/ecpg/preproc/descriptor.c +++ b/src/interfaces/ecpg/preproc/descriptor.c @@ -121,7 +121,10 @@ drop_descriptor(char *name, char *connection) } } } - mmerror(PARSE_ERROR, ET_WARNING, "descriptor \"%s\" does not exist", name); + if (connection) + mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection); + else + mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name); } struct descriptor @@ -141,9 +144,18 @@ lookup_descriptor(char *name, char *connection) || (connection && i->connection && strcmp(connection, i->connection) == 0)) return i; + if (connection && !i->connection) + { + /* overwrite descriptor's connection */ + i->connection = mm_strdup(connection); + return i; + } } } - mmerror(PARSE_ERROR, ET_WARNING, "descriptor \"%s\" does not exist", name); + if (connection) + mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection); + else + mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name); return NULL; } diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons index b6e3412cef..87c8dff928 100644 --- a/src/interfaces/ecpg/preproc/ecpg.addons +++ b/src/interfaces/ecpg/preproc/ecpg.addons @@ -132,13 +132,20 @@ ECPG: stmtViewStmt rule } | ECPGDescribe { - fprintf(base_yyout, "{ ECPGdescribe(__LINE__, %d, %s,", compat, $1); + check_declared_list($1.stmt_name); + + fprintf(base_yyout, "{ ECPGdescribe(__LINE__, %d, %d, %s, %s,", compat, $1.input, connection ? connection : "NULL", $1.stmt_name); dump_variables(argsresult, 1); fputs("ECPGt_EORT);", base_yyout); fprintf(base_yyout, "}"); output_line_number(); - free($1); + free($1.stmt_name); + if (connection != NULL) + { + free(connection); + connection = NULL; + } } | ECPGDisconnect { diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index 5263df2b6e..e3f5a4b903 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -590,13 +590,14 @@ check_declared_list(const char *name) struct declared_list *ptr = NULL; for (ptr = g_declared_list; ptr != NULL; ptr = ptr -> next) { + if (!ptr->connection) + continue; if (strcmp(name, ptr -> name) == 0) { - if (ptr -> connection) - { - connection = mm_strdup(ptr -> connection); - return true; - } + if (connection) + mmerror(PARSE_ERROR, ET_WARNING, "connection %s is overwritten to %s.", connection, ptr->connection); + connection = mm_strdup(ptr -> connection); + return true; } } return false; @@ -621,4 +622,5 @@ check_declared_list(const char *name) struct su_symbol struct_union; struct prep prep; struct exec exec; + struct describe describe; } diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 96c55349e8..2bfb60a7d2 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -1101,41 +1101,33 @@ UsingConst: Iconst { $$ = $1; } */ ECPGDescribe: SQL_DESCRIBE INPUT_P prepared_name using_descriptor { - const char *con = connection ? connection : "NULL"; - mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement"); - $$ = (char *) mm_alloc(sizeof("1, , ") + strlen(con) + strlen($3)); - sprintf($$, "1, %s, %s", con, $3); + $$.input = 1; + $$.stmt_name = $3; } | SQL_DESCRIBE opt_output prepared_name using_descriptor { - const char *con = connection ? connection : "NULL"; struct variable *var; - var = argsinsert->variable; remove_variable_from_list(&argsinsert, var); add_variable_to_head(&argsresult, var, &no_indicator); - $$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3)); - sprintf($$, "0, %s, %s", con, $3); + $$.input = 0; + $$.stmt_name = $3; } | SQL_DESCRIBE opt_output prepared_name into_descriptor { - const char *con = connection ? connection : "NULL"; - $$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3)); - sprintf($$, "0, %s, %s", con, $3); + $$.input = 0; + $$.stmt_name = $3; } | SQL_DESCRIBE INPUT_P prepared_name into_sqlda { - const char *con = connection ? connection : "NULL"; - mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement"); - $$ = (char *) mm_alloc(sizeof("1, , ") + strlen(con) + strlen($3)); - sprintf($$, "1, %s, %s", con, $3); + $$.input = 1; + $$.stmt_name = $3; } | SQL_DESCRIBE opt_output prepared_name into_sqlda { - const char *con = connection ? connection : "NULL"; - $$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3)); - sprintf($$, "0, %s, %s", con, $3); + $$.input = 0; + $$.stmt_name = $3; } ; @@ -1862,8 +1854,8 @@ c_anything: ecpg_ident { $$ = $1; } | ':' { $$ = mm_strdup(":"); } ; -DeallocateStmt: DEALLOCATE prepared_name { $$ = $2; } - | DEALLOCATE PREPARE prepared_name { $$ = $3; } +DeallocateStmt: DEALLOCATE prepared_name { check_declared_list($2); $$ = $2; } + | DEALLOCATE PREPARE prepared_name { check_declared_list($3); $$ = $3; } | DEALLOCATE ALL { $$ = mm_strdup("all"); } | DEALLOCATE PREPARE ALL { $$ = mm_strdup("all"); } ; diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type index e8c36119ed..d1cde691c0 100644 --- a/src/interfaces/ecpg/preproc/ecpg.type +++ b/src/interfaces/ecpg/preproc/ecpg.type @@ -10,7 +10,6 @@ %type ECPGDeclaration %type ECPGDeclare %type ECPGDeclareStmt -%type ECPGDescribe %type ECPGDisconnect %type ECPGExecuteImmediateStmt %type ECPGFree @@ -143,3 +142,5 @@ %type var_type %type action + +%type ECPGDescribe diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index 01ccb74fdc..d8ded7ea24 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -207,4 +207,10 @@ struct fetch_desc char *name; }; +struct describe +{ + int input; + char *stmt_name; +}; + #endif /* _ECPG_PREPROC_TYPE_H */