API documentation

This chapter briefly explains some implementation detail.

exception pglast.Error

Top level error exception.

pglast.__author__ = 'Lele Gaifax <lele@metapensiero.it>'

Package’s author.

pglast.__version__ = 'v7.3'

Package’s version.

pglast.parse_plpgsql(statement)

Parse the given PLPGSQL statement and return its tokens stream.

Note

This is currently somewhat of limited usefulness, because neither libpg_query 1 nor pglast expose proper AST nodes for the PostgreSQL’s procedural extension language, and thus it returns the raw tree, represented by plain Python structures such as lists, dictionaries and scalar values.

Consider the following examples, two different ways to parse the same SQL statement. The first uses parse_plpgsql():

from pprint import pprint
from pglast import parse_plpgsql

STMT = '''\
CREATE FUNCTION add (a integer, b integer)
RETURNS integer AS $$
BEGIN
  RETURN a + b;
END;
$$ LANGUAGE plpgsql
'''

as_plpgsql = parse_plpgsql(STMT)
pprint(as_plpgsql, depth=6)

and emits this structure:

[{'PLpgSQL_function': {'action': {'PLpgSQL_stmt_block': {'body': [{...}],
                                                         'lineno': 2}},
                       'datums': [{'PLpgSQL_var': {'datatype': {...},
                                                   'refname': 'a'}},
                                  {'PLpgSQL_var': {'datatype': {...},
                                                   'refname': 'b'}},
                                  {'PLpgSQL_var': {'datatype': {...},
                                                   'refname': 'found'}}]}}]

As you can see, is just a list of plain Python dictionaries, more or less representing syntax tokens.

If you use parse_sql() instead:

from pglast import parse_sql

as_sql = parse_sql(STMT)
pprint([stmt(skip_none=True) for stmt in as_sql])

you obtain a richer representation2 of the statement:

[{'@': 'RawStmt',
  'stmt': {'@': 'CreateFunctionStmt',
           'funcname': ({'@': 'String', 'sval': 'add'},),
           'is_procedure': False,
           'options': ({'@': 'DefElem',
                        'arg': ({'@': 'String',
                                 'sval': '\nBEGIN\n  RETURN a + b;\nEND;\n'},),
                        'defaction': {'#': 'DefElemAction',
                                      'name': 'DEFELEM_UNSPEC',
                                      'value': 0},
                        'defname': 'as',
                        'location': ...},
                       {'@': 'DefElem',
                        'arg': {'@': 'String', 'sval': 'plpgsql'},
                        'defaction': {'#': 'DefElemAction',
                                      'name': 'DEFELEM_UNSPEC',
                                      'value': 0},
                        'defname': 'language',
                        'location': ...}),
           'parameters': ({'@': 'FunctionParameter',
                           'argType': {'@': 'TypeName',
                                       'location': ...,
                                       'names': ({'@': 'String',
                                                  'sval': 'pg_catalog'},
                                                 {'@': 'String',
                                                  'sval': 'int4'}),
                                       'pct_type': False,
                                       'setof': False,
                                       'typemod': -1},
                           'mode': {'#': 'FunctionParameterMode',
                                    'name': 'FUNC_PARAM_DEFAULT',
                                    'value': 'd'},
                           'name': 'a'},
                          {'@': 'FunctionParameter',
                           'argType': {'@': 'TypeName',
                                       'location': ...,
                                       'names': ({'@': 'String',
                                                  'sval': 'pg_catalog'},
                                                 {'@': 'String',
                                                  'sval': 'int4'}),
                                       'pct_type': False,
                                       'setof': False,
                                       'typemod': -1},
                           'mode': {'#': 'FunctionParameterMode',
                                    'name': 'FUNC_PARAM_DEFAULT',
                                    'value': 'd'},
                           'name': 'b'}),
           'replace': False,
           'returnType': {'@': 'TypeName',
                          'location': ...,
                          'names': ({'@': 'String', 'sval': 'pg_catalog'},
                                    {'@': 'String', 'sval': 'int4'}),
                          'pct_type': False,
                          'setof': False,
                          'typemod': -1}},
  'stmt_len': 0,
  'stmt_location': 0}]
1

See also https://github.com/pganalyze/libpg_query/issues/110.

2

location values has been masqueraded for test purposes.

pglast.prettify(statement, safety_belt=False, preserve_comments=False, **options)

Render given statement into a prettified format.

Parameters
  • statement (str) – the SQL statement(s)

  • safety_belt (bool) – whether to perform a safe check against bugs in pglast’s serialization

  • preserve_comments (bool) – whether comments shall be preserved, defaults to not

  • **options – any keyword option accepted by IndentedStream constructor

Returns

a string with the equivalent prettified statement(s)

When safety_belt is True, the resulting statement is parsed again and its AST compared with the original statement: if they don’t match, a warning is emitted and the original statement is returned. By default it is False, so no double check is done.

pglast.split()

Split the given stmts string into a sequence of the single SQL statements.

By default this uses the parser to perform the job; when with_parser is False the scanner variant is used, indicated when the statements may contain parse errors.

When only_slices is True, return a sequence of slice instances, one for each statement, instead of statements text.

NB: leading and trailing whitespace are removed from the statements.