Fix function signature generation for reverse engineered SQL. Fixes #1674

1) In SQL pane, the signature in comments had arguments with name and type, Now it will show arguments with type only.

2) There is no indent+newline between arguments (there isn't even a space). - Fixed

3) The default value for the last argument is omitted. - Fixed
Last argument is omitted because the value for the last argument we got from table is empty.
Now we form function signature in the get_definition.sql using 'pg_catalog.pg_get_function_arguments' method.

Above changes will reflect in Functions, Procedures & Trigger function Nodes.
This commit is contained in:
Surinder Kumar 2016-09-14 10:59:11 +01:00 committed by Dave Page
parent 751327eacc
commit f2469d113c
25 changed files with 120 additions and 33 deletions

View File

@ -938,18 +938,42 @@ class FunctionView(PGChildNodeView, DataTypeReader):
if self.node_type == 'procedure':
object_type = 'procedure'
# Get SQL to create Function
status, func_def = self._get_sql(gid, sid, did, scid, resp_data,
None, True)
# Get Schema Name from its OID.
if 'pronamespace' in resp_data:
resp_data['pronamespace'] = self._get_schema(resp_data[
'pronamespace'])
SQL = render_template("/".join([self.sql_template_path,
'get_definition.sql']
), data=resp_data,
fnid=fnid, scid=scid)
status, res = self.conn.execute_2darray(SQL)
if not status:
return internal_server_error(errormsg=func_def)
return internal_server_error(errormsg=res)
name = resp_data['pronamespace'] + "." + resp_data['name_with_args']
# Add newline and tab before each argument to format
name_with_default_args = res['rows'][0]['name_with_default_args'].replace(', ', ',\r\t').replace('(', '(\r\t')
# Create mode
# Parse privilege data
if 'acl' in resp_data:
resp_data['acl'] = parse_priv_to_db(resp_data['acl'], ['X'])
# generate function signature
header_func_name = '{0}.{1}({2})'.format(
resp_data['pronamespace'],
resp_data['proname'],
resp_data['proargtypenames']
)
# Generate sql for "SQL panel"
# func_def is procedure signature with default arguments
# query_for - To distinguish the type of call
func_def = render_template("/".join([self.sql_template_path,
'create.sql']),
data=resp_data, query_type="create")
data=resp_data, query_type="create",
func_def=name_with_default_args,
query_for="sql_panel")
else:
object_type = 'function'
@ -962,7 +986,13 @@ class FunctionView(PGChildNodeView, DataTypeReader):
if 'acl' in resp_data:
resp_data['acl'] = parse_priv_to_db(resp_data['acl'], ['X'])
# Create mode
# generate function signature
header_func_name = '{0}.{1}({2})'.format(
resp_data['pronamespace'],
resp_data['proname'],
resp_data['proargtypenames']
)
SQL = render_template("/".join([self.sql_template_path,
'get_definition.sql']
), data=resp_data,
@ -972,8 +1002,9 @@ class FunctionView(PGChildNodeView, DataTypeReader):
if not status:
return internal_server_error(errormsg=res)
name = res['rows'][0]['name']
# Create mode
# Add newline and tab before each argument to format
name_with_default_args = res['rows'][0]['name_with_default_args'].replace(', ', ',\r\t').replace('(', '(\r\t')
if hasattr(str, 'decode'):
if resp_data['prosrc']:
resp_data['prosrc'] = resp_data['prosrc'].decode(
@ -983,15 +1014,21 @@ class FunctionView(PGChildNodeView, DataTypeReader):
resp_data['prosrc_c'] = resp_data['prosrc_c'].decode(
'utf-8'
)
# Generate sql for "SQL panel"
# func_def is function signature with default arguments
# query_for - To distinguish the type of call
func_def = render_template("/".join([self.sql_template_path,
'create.sql']),
data=resp_data, query_type="create")
data=resp_data, query_type="create",
func_def=name_with_default_args,
query_for="sql_panel")
sql_header = """-- {0}: {1}
-- DROP {0} {1};
""".format(object_type.upper(), name)
""".format(object_type.upper(), header_func_name)
if hasattr(str, 'decode'):
sql_header = sql_header.decode('utf-8')

View File

@ -3,12 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
{% else %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.args %}
{% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}}{% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
{% endif -%}
RETURNS{% if data.proretset and data.prorettypename.startswith('SETOF ') %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ conn|qtTypeIdent(data.prorettypename) }}{% else %} {{ conn|qtTypeIdent(data.prorettypename) }}{% endif %}
LANGUAGE {{ data.lanname|qtLiteral }}

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,12 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
{% else %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.args %}
{% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
{% endif -%}
RETURNS{% if data.proretset and data.prorettypename.startswith('SETOF ') %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ conn|qtTypeIdent(data.prorettypename) }}{% else %} {{ conn|qtTypeIdent(data.prorettypename) }}{% endif %}
LANGUAGE {{ data.lanname|qtLiteral }}

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,12 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
{% else %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.args %}
{% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor %}
{% endif -%}
)
{% endif %}
RETURNS{% if data.proretset and data.prorettypename.startswith('SETOF ') %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ conn|qtTypeIdent(data.prorettypename) }}{% else %} {{ conn|qtTypeIdent(data.prorettypename) }}{% endif %}
LANGUAGE {{ data.lanname|qtLiteral }}

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,12 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
{% else %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.args %}
{% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
{% endif -%}
RETURNS{% if data.proretset and data.prorettypename.startswith('SETOF ') %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ conn|qtTypeIdent(data.prorettypename) }}{% else %} {{ conn|qtTypeIdent(data.prorettypename) }}{% endif %}
LANGUAGE {{ data.lanname|qtLiteral }}

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,12 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
{% else %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.args %}
{% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
{% endif -%}
RETURNS{% if data.proretset and data.prorettypename.startswith('SETOF ') %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ conn|qtTypeIdent(data.prorettypename) }}{% else %} {{ conn|qtTypeIdent(data.prorettypename) }}{% endif %}
LANGUAGE {{ data.lanname|qtLiteral }}

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,12 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
{% else %}
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.args %}
{% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
{% endif -%}
)
{% endif -%}
RETURNS{% if data.proretset and data.prorettypename.startswith('SETOF ') %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ conn|qtTypeIdent(data.prorettypename) }}{% else %} {{ conn|qtTypeIdent(data.prorettypename) }}{% endif %}
LANGUAGE {{ data.lanname|qtLiteral }}

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,11 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE OR REPLACE PROCEDURE {{func_def}}
{% else %}
CREATE OR REPLACE PROCEDURE {{ conn|qtIdent(data.pronamespace, data.name) }}{% if data.args is defined %}
({% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor -%}
){% endif %}
{% endif %}
)
{% endif %}
AS
{{ data.prosrc }};

View File

@ -1,7 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,11 +3,16 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE OR REPLACE PROCEDURE {{func_def}}
{% else %}
CREATE OR REPLACE PROCEDURE {{ conn|qtIdent(data.pronamespace, data.name) }}{% if data.args is defined %}
({% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor -%}
){% endif %}
{% endif %}
)
{% endif %}
AS
{{ data.prosrc }};

View File

@ -1,7 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -3,11 +3,15 @@
{% import 'macros/functions/variable.macros' as VARIABLE %}
{% set is_columns = [] %}
{% if data %}
{% if query_for == 'sql_panel' and func_def is defined %}
CREATE OR REPLACE PROCEDURE {{func_def}}
{% else %}
CREATE OR REPLACE PROCEDURE {{ conn|qtIdent(data.pronamespace, data.name) }}{% if data.args is defined %}
({% for p in data.args %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname)}} {% endif %}{% if p.argtype %}{{ conn|qtTypeIdent(p.argtype) }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
{% if not loop.last %}, {% endif %}
{% endfor -%}
){% endif %}
{% endif %}
{% if query_type != 'create' %}
{{ data.provolatile }}{% if data.proleakproof %} LEAKPROOF {% elif not data.proleakproof %} NOT LEAKPROOF {% endif %}

View File

@ -1,7 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog
.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN

View File

@ -1,6 +1,7 @@
SELECT
pg_get_functiondef({{fnid}}::oid) AS func_def,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_identity_arguments(pr.oid), '') || ')' as name,
nspname || '.' || pr.proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(pr.oid), '') || ')' as name_with_default_args
FROM
pg_proc pr
JOIN