I have the following PLSQL code which I am processing with Antlr4 in Python. I ma having trouble extracting the function parameter name and related details.
CREATE OR REPLACE
FUNCTION getcost ( p_prod_id IN VARCHAR2 , p_date IN DATE) RETURN number AS
The ParseTree output for this:
╚═ sql_script
╠═ unit_statement
║ ╚═ create_function_body
║ ╠═ "CREATE" (CREATE)
║ ╠═ "OR" (OR)
║ ╠═ "REPLACE" (REPLACE)
║ ╠═ "FUNCTION" (FUNCTION)
║ ╠═ function_name
║ ║ ╚═ identifier
║ ║ ╚═ id_expression
║ ║ ╚═ regular_id
║ ║ ╚═ "getcost" (REGULAR_ID)
║ ╠═ "(" (LEFT_PAREN)
║ ╠═ parameter
║ ║ ╠═ parameter_name
║ ║ ║ ╚═ identifier
║ ║ ║ ╚═ id_expression
║ ║ ║ ╚═ regular_id
║ ║ ║ ╚═ "p_prod_id" (REGULAR_ID)
║ ║ ╠═ "IN" (IN)
║ ║ ╚═ type_spec
║ ║ ╚═ datatype
║ ║ ╚═ native_datatype_element
║ ║ ╚═ "VARCHAR2" (VARCHAR2)
║ ╠═ "," (COMMA)
║ ╠═ parameter
║ ║ ╠═ parameter_name
║ ║ ║ ╚═ identifier
║ ║ ║ ╚═ id_expression
║ ║ ║ ╚═ regular_id
║ ║ ║ ╚═ "p_date" (REGULAR_ID)
║ ║ ╠═ "IN" (IN)
║ ║ ╚═ type_spec
║ ║ ╚═ datatype
║ ║ ╚═ native_datatype_element
║ ║ ╚═ "DATE" (DATE)
║ ╠═ ")" (RIGHT_PAREN)
║ ╠═ "RETURN" (RETURN)
║ ╠═ type_spec
║ ║ ╚═ datatype
║ ║ ╚═ native_datatype_element
║ ║ ╚═ "number" (NUMBER)
║
The python code is:
def enterParameter(self, ctx:PlSqlParser.ParameterContext):
print(ctx.toStringTree(recog=parser))
param_name = None
if ctx.parameter_name:
if ctx.parameter_name.identifier() and ctx.parameter_name.identifier().id_expression():
param_name = ctx.parameter_name.identifier().id_expression().regular_id().getText()
param_type = None
if ctx.type_spec and ctx.type_spec.datatype:
if ctx.type_spec.datatype.native_datatype_element():
param_type = ctx.type_spec.datatype.native_datatype_element().getText()
default_value = None
print(f"Parameter: {param_name}, Type: {param_type}, Def: {default_value}")
The output from the print statement is:
(parameter (parameter_name (identifier (id_expression (regular_id p_prod_id)))) IN (type_spec (datatype (native_datatype_element VARCHAR2))))
But I get the following error:
if ctx.parameter_name.identifier() and ctx.parameter_name.identifier().id_expression():
AttributeError: 'function' object has no attribute 'identifier'
If I use ctx.getChild(0).getText()
to get the parameter name it works, but I don't want to rely on hardcoded indices, and I also do not understand why this isn't working.
The parameter_name
in the context is a fuction, beacuse if the context can contain more than one parameter the integer parameter defines the index of it.
so please change you code to this:
ctx.parameter_name().identifier()
And I wonder why your function has no return value, so for multiple parameters the param_name
variable will always change.
Of course, this could be intentional.