修复create package中报错位置不准确的问题。

修复方案在CreatePackageStmt中添加了pkgspec_location和pkgspec_prefix_len成员变量,用于保存package body的位置和添加的SQL的长度,报错时重新计算报错编译位置。
This commit is contained in:
dongxu.wei
2022-09-13 17:00:43 +08:00
parent ab3d6c1bb1
commit 71755991b2
7 changed files with 175 additions and 112 deletions

View File

@ -5184,6 +5184,8 @@ static CreatePackageStmt* _copyCreatePackageStmt(const CreatePackageStmt* from)
COPY_NODE_FIELD(pkgname);
COPY_SCALAR_FIELD(pkgsecdef);
COPY_STRING_FIELD(pkgspec);
COPY_SCALAR_FIELD(pkgspec_location);
COPY_SCALAR_FIELD(pkgspec_prefix_len);
return newnode;
}

View File

@ -13487,6 +13487,7 @@ CreatePackageStmt:
CREATE opt_or_replace PACKAGE pkg_name invoker_rights as_is {pg_yyget_extra(yyscanner)->core_yy_extra.include_ora_comment = true;}
{
u_sess->plsql_cxt.package_as_line = GetLineNumber(t_thrd.postgres_cxt.debug_query_string, @6);
CreatePackageStmt *n = makeNode(CreatePackageStmt);
char *pkgNameBegin = NULL;
char *pkgNameEnd = NULL;
char *pkgName = NULL;
@ -13519,7 +13520,7 @@ CreatePackageStmt:
tok = yychar;
yychar = YYEMPTY;
}
int proc_start_pos = yylloc;
int proc_start_pos = n->pkgspec_location = yylloc;
u_sess->plsql_cxt.package_first_line = GetLineNumber(t_thrd.postgres_cxt.debug_query_string, yylloc);
// Scan whole stmt.
@ -13586,6 +13587,8 @@ CreatePackageStmt:
initStringInfo(&content_info);
appendStringInfo(&content_info, "%s", PACKAGE_STR);
appendStringInfo(&content_info, "%s", DECLARE_STR);
n->pkgspec_prefix_len = content_info.len;
n->pkgspec_location -= 1;
appendBinaryStringInfo(&content_info, yyextra->core_yy_extra.scanbuf + proc_start_pos - 1, name_start_pos - proc_start_pos + 1);
char* pkg_spec_str = content_info.data;
@ -13627,7 +13630,6 @@ CreatePackageStmt:
parser_yyerror("package name end is not match the one begin!");
}
#endif
CreatePackageStmt *n = makeNode(CreatePackageStmt);
n->replace = $2;
n->pkgname = $4;
n->pkgspec = pkg_spec_str;

View File

@ -211,11 +211,11 @@ static PLpgSQL_expr *read_cursor_args(PLpgSQL_var *cursor,
int until, const char *expected);
static List *read_raise_options(void);
static int errstate = ERROR;
static char* get_proc_str(int tok);
static DefElem* get_proc_str(int tok);
static char* get_init_proc(int tok);
static char* get_attrname(int tok);
static AttrNumber get_assign_attrno(PLpgSQL_datum* target, char* attrname);
static void raw_parse_package_function(char* proc_str);
static void raw_parse_package_function(char* proc_str, int location, int leaderlen);
static void checkFuncName(List* funcname);
static void IsInPublicNamespace(char* varname);
static void SetErrorState();
@ -317,6 +317,7 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
PLpgSQL_case_when *casewhen;
PLpgSQL_rec_attr *recattr;
Node *plnode;
DefElem *def;
}
%type <plnode> assign_el
@ -340,7 +341,8 @@ static void processFunctionRecordOutParam(int varno, Oid funcoid, int* outparam)
%type <forvariable> for_variable
%type <stmt> for_control forall_control
%type <str> any_identifier opt_block_label opt_label goto_block_label label_name spec_proc init_proc
%type <def> spec_proc
%type <str> any_identifier opt_block_label opt_label goto_block_label label_name init_proc
%type <str> opt_rollback_to opt_savepoint_name savepoint_name attr_name
%type <list> proc_sect proc_stmts stmt_elsifs stmt_else forall_body
@ -1476,20 +1478,22 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no
}
| K_FUNCTION {u_sess->parser_cxt.is_procedure=false;} spec_proc
{
DefElem *def = $3;
u_sess->plsql_cxt.procedure_start_line = GetLineNumber(u_sess->plsql_cxt.curr_compile_context->core_yy->scanbuf, @1);
u_sess->plsql_cxt.plpgsql_yylloc = @1;
u_sess->plsql_cxt.isCreateFunction = true;
raw_parse_package_function($3);
raw_parse_package_function(def->defname, def->location, def->begin_location);
u_sess->plsql_cxt.isCreateFunction = false;
u_sess->plsql_cxt.procedure_start_line = 0;
u_sess->plsql_cxt.plpgsql_yylloc = 0;
}
| K_PROCEDURE {u_sess->parser_cxt.is_procedure=true;} spec_proc
{
DefElem *def = $3;
u_sess->plsql_cxt.procedure_start_line = GetLineNumber(u_sess->plsql_cxt.curr_compile_context->core_yy->scanbuf, @1);
u_sess->plsql_cxt.plpgsql_yylloc = plpgsql_yylloc;
u_sess->plsql_cxt.isCreateFunction = true;
raw_parse_package_function($3);
raw_parse_package_function(def->defname, def->location, def->begin_location);
u_sess->plsql_cxt.isCreateFunction = false;
u_sess->plsql_cxt.procedure_start_line = 0;
u_sess->plsql_cxt.plpgsql_yylloc = 0;
@ -8174,15 +8178,18 @@ read_sql_construct(int until,
/*
* get function declare or definition string in package.
*/
static char *
static DefElem*
get_proc_str(int tok)
{
int blocklevel = 0;
int pre_tok = 0;
DefElem *def;
if (u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package == NULL) {
yyerror("not allowed create procedure in function or procedure.");
}
tok = yylex();
tok = yylex();
def = makeDefElem(NULL, NULL); /* make an empty DefElem */
def->location = yylloc;
StringInfoData ds;
bool is_defining_proc = false;
char * spec_proc_str = NULL;
@ -8196,6 +8203,7 @@ get_proc_str(int tok)
} else {
appendStringInfoString(&ds, " CREATE OR REPLACE PROCEDURE ");
}
def->begin_location = ds.len;
u_sess->parser_cxt.in_package_function_compile = true;
while(true)
{
@ -8270,9 +8278,10 @@ get_proc_str(int tok)
u_sess->parser_cxt.isFunctionDeclare = false;
}
def->defname = pstrdup(ds.data);
spec_proc_str = pstrdup(ds.data);
pfree_ext(ds.data);
return spec_proc_str;
return def;
}
static char* get_init_proc(int tok)
{
@ -12081,14 +12090,39 @@ parse_lob_open_close(int location)
return NULL;
}
static void raw_parse_package_function(char* proc_str)
static void raw_parse_package_function_callback(void *arg)
{
sql_error_callback_arg *cbarg = (sql_error_callback_arg*)arg;
int cur_pos = geterrposition();
if (cur_pos > cbarg->leaderlen)
{
cur_pos += cbarg->location - cbarg->leaderlen;
errposition(cur_pos);
}
}
static void raw_parse_package_function(char* proc_str, int location, int leaderlen)
{
if (u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile_package != NULL)
{
sql_error_callback_arg cbarg;
ErrorContextCallback syntax_errcontext;
List* raw_parsetree_list = NULL;
u_sess->plsql_cxt.plpgsql_yylloc = plpgsql_yylloc;
u_sess->plsql_cxt.rawParsePackageFunction = true;
cbarg.location = location;
cbarg.leaderlen = leaderlen;
syntax_errcontext.callback = raw_parse_package_function_callback;
syntax_errcontext.arg = &cbarg;
syntax_errcontext.previous = t_thrd.log_cxt.error_context_stack;
t_thrd.log_cxt.error_context_stack = &syntax_errcontext;
raw_parsetree_list = raw_parser(proc_str);
/* Restore former ereport callback */
t_thrd.log_cxt.error_context_stack = syntax_errcontext.previous;
CreateFunctionStmt* stmt;
u_sess->plsql_cxt.rawParsePackageFunction = false;
int rc = 0;

View File

@ -60,6 +60,22 @@
#include "tcop/utility.h"
static void create_package_error_callback(void *arg)
{
CreatePackageStmt* stmt = (CreatePackageStmt*)arg;
int cur_pos;
if (stmt->pkgspec_location <= 0)
return;
cur_pos = geterrposition();
if (cur_pos > 0)
{
cur_pos += (stmt->pkgspec_location - stmt->pkgspec_prefix_len);
errposition(cur_pos);
}
}
void CreatePackageCommand(CreatePackageStmt* stmt, const char* queryString)
{
#ifdef ENABLE_MULTIPLE_NODES
@ -72,6 +88,7 @@ void CreatePackageCommand(CreatePackageStmt* stmt, const char* queryString)
char* pkgname = NULL;
char* pkgspecsrc = NULL;
Oid pkgOwner;
ErrorContextCallback err_context;
/* Convert list of names to a name and namespace */
namespaceId = QualifiedNameGetCreationNamespace(stmt->pkgname, &pkgname);
@ -122,7 +139,13 @@ void CreatePackageCommand(CreatePackageStmt* stmt, const char* queryString)
errcause("package name is null"),
erraction("rename package")));
}
err_context.arg = (void*)stmt;
err_context.previous = t_thrd.log_cxt.error_context_stack;
err_context.callback = create_package_error_callback;
t_thrd.log_cxt.error_context_stack = &err_context;
packageId = PackageSpecCreate(namespaceId, pkgname, pkgOwner, pkgspecsrc, stmt->replace, stmt->pkgsecdef);
t_thrd.log_cxt.error_context_stack = err_context.previous;
/* Advance cmd counter to make the package visible */
if (OidIsValid(packageId)) {

View File

@ -2150,6 +2150,8 @@ typedef struct CreatePackageStmt {
List* pkgname; /* qualified name of function to create */
bool pkgsecdef; /* package security definer or invoker */
char* pkgspec; /* content of package spec */
int pkgspec_location; /* pkgspec start location */
int pkgspec_prefix_len; /* inserted string length in pkgspec */
} CreatePackageStmt;
typedef struct CreatePackageBodyStmt {

View File

@ -290,7 +290,7 @@ end pkg1;
/
NOTICE: syntax error at or near "F"
LINE 3: procedure proc1(c ff%F);
^
^
CONTEXT: compilation of PL/pgSQL package near line 1
ERROR: Debug mod,create procedure has error.
DETAIL: N/A

View File

@ -390,167 +390,167 @@ end AA;
/
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 4: procedure aa_bb(p_self in out nocopy json, pair_name varch...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 5: procedure aa_bb(p_self in out nocopy json, pair_name varch...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 6: procedure aa_bb(p_self in out nocopy json, pair_name varch...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 7: procedure aa_bb(p_self in out nocopy json, pair_name varch...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 8: ...procedure aa_check_duplicate(p_self in out nocopy json, v_se...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 9: procedure aa_remove_duplicates(p_self in out nocopy json);
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 11: procedure aa_bb(p_self in out nocopy json, pair_name varch...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 12: procedure aa_bb(p_self in out nocopy json, pair_name varch...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "position"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 16: function aa_get(p_self in json, position pls_integer) retu...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "clob"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 21: ...dure aa_to_clob(p_self in json, buf in out nocopy clob, spac...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 28: procedure aa_path_bb(p_self in out nocopy json, json_path ...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 29: procedure aa_path_bb(p_self in out nocopy json, json_path ...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 30: procedure aa_path_bb(p_self in out nocopy json, json_path ...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 31: procedure aa_path_bb(p_self in out nocopy json, json_path ...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 32: procedure aa_path_bb(p_self in out nocopy json, json_path ...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 33: procedure aa_path_bb(p_self in out nocopy json, json_path ...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 35: procedure aa_path_remove(p_self in out nocopy json, json_p...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 41: procedure aa_append(p_self in out nocopy json_list, elem j...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 42: procedure aa_append(p_self in out nocopy json_list, elem v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 43: procedure aa_append(p_self in out nocopy json_list, elem n...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 44: procedure aa_append(p_self in out nocopy json_list, elem b...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 45: procedure aa_append(p_self in out nocopy json_list, elem j...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 47: procedure aa_replace(p_self in out nocopy json_list, posit...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 48: procedure aa_replace(p_self in out nocopy json_list, posit...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 49: procedure aa_replace(p_self in out nocopy json_list, posit...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 50: procedure aa_replace(p_self in out nocopy json_list, posit...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 51: procedure aa_replace(p_self in out nocopy json_list, posit...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 54: procedure aa_remove(p_self in out nocopy json_list, positi...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "position"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "clob"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "clob"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
LINE 55: procedure aa_remove_first(p_self in out nocopy json_list);
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 56: procedure aa_remove_last(p_self in out nocopy json_list);
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "position"
LINE 57: function aa_get(p_self in json_list, position pls_integer)...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "clob"
LINE 3: procedure aa_remove(p_self in out nocopy json, pair_name v...
^
LINE 63: ...aa_to_clob(p_self in json_list, buf in out nocopy clob, spac...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 68: procedure aa_path_bb(p_self in out nocopy json_list, json_...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 69: procedure aa_path_bb(p_self in out nocopy json_list, json_...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 70: procedure aa_path_bb(p_self in out nocopy json_list, json_...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 71: procedure aa_path_bb(p_self in out nocopy json_list, json_...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 72: procedure aa_path_bb(p_self in out nocopy json_list, json_...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "json_list"
LINE 74: procedure aa_path_remove(p_self in out nocopy json_list, j...
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "clob"
LINE 83: ...aa_get_string(p_self in json_value, buf in out nocopy clob);
^
CONTEXT: compilation of PL/pgSQL package near line 1
NOTICE: syntax error at or near "clob"
LINE 96: ...a_to_clob(p_self in json_value, buf in out nocopy clob, spac...
^
CONTEXT: compilation of PL/pgSQL package near line 1
ERROR: Debug mod,create procedure has error.
DETAIL: N/A