# `pglast.stream` — The serialization machinery

class pglast.stream.OutputStream

  A stream that has a concept of a pending separator between consecutive writes.

  maybe_write_space(nextc=None, _special_chars={'"', '$', "'", '*', '+', '-', '/', '<', '=', '>', '@', '_'})

    Emit a space when needed.

    Parameters:

      nextc – either None or the next character that will be written

    Returns:

      the number of characters written to the stream

    If the last character written was neither a space nor an open parentheses, and nextc is either `None` or a special character, then emit a single whitespace.

  separator()

    Possibly insert a single whitespace character before next output.

    When the last character written is not a space, set the pending_separator flag to `True`: the next call to `write()` will prepend a single whitespace to its argument if that begins with an alphanumeric character.

  show(where=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>)

    Emit current stream content, by default to stderr, to aid debugging.

  swrite(s)

    Shortcut for `self.maybe_write_space(s[0]); self.write(s)`.

  swrites(s)

    Shortcut for `self.swrite(s); self.separator()`.

  write(s)

    Emit string s.

    Parameters:

      s (str) – the string to emit

    Returns:

      the number of characters written to the stream

    When s is not empty and pending_separator is `True` and the first character of s is alphanumeric, emit a single whitespace before writing out s and then reset pending_separator to `False`.

  writes(s)

    Shortcut for `self.write(s); self.separator()`.

class pglast.stream.RawStream(separate_statements=1, special_functions=False, comma_at_eoln=False, semicolon_after_last_statement=False, comments=None, remove_pg_catalog_from_functions=False)

  Basic SQL parse tree writer.

  Parameters:

    - separate_statements (int) – `1` by default, tells how many empty lines should separate statements

    - special_functions (bool) – `False` by default, when `True` some functions are treated in a special way and emitted as equivalent constructs

    - comma_at_eoln (bool) – `False` by default, when `True` put the comma right after each item instead of at the beginning of the next item line

    - semicolon_after_last_statement (bool) – `False` by default, when `True` add a semicolon after the last statement, otherwise it is emitted only as a separator between multiple statements

    - comments – optional sequence of tuples with the comments extracted from the statement

    - remove_pg_catalog_from_functions (bool) – `False` by default, when `True` remove the pg_catalog schema from functions

  This augments `OutputStream` and implements the basic machinery needed to serialize the parse tree produced by `parse_sql()` back to a textual representation, without any adornment.

  __call__(sql, plpgsql=False)

    Main entry point: execute `print_node()` on each statement in sql.

    Parameters:

      - sql – the SQL statement

      - plpgsql (bool) – whether sql is really a `plpgsql` statement

    Returns:

      a string with the equivalent SQL obtained by serializing the syntax tree

    The sql statement may be either a `str` containing the `SQL` in textual form, or a concrete `ast.Node` instance or a tuple of them.

  dedent()

    Do nothing, shall be overridden by the prettifier subclass.

  expression(need_parens)

    Create a context manager usable to conditionally wrap something within parentheses.

    Parameters:

      need_parens (bool) – whether to emit opening and closing parentheses

    This method used to be used for subexpressions, but now is used to emit almost anything that goes within parentheses.

  get_printer_for_function(name)

    Look for a specific printer for function name in `SPECIAL_FUNCTIONS`.

    Parameters:

      name (str) – the qualified name of the function

    Returns:

      either `None` or a callable

    When the option special_functions is `True`, return the printer function associated with name, if present. In all other cases return `None`.

  indent(amount=0, relative=True)

    Do nothing, shall be overridden by the prettifier subclass.

  newline()

    Emit a single whitespace, shall be overridden by the prettifier subclass.

  print_comment(comment)

    Print the given comment, unconditionally in the `C` syntax, joining all lines.

  print_list(nodes, sep=',', relative_indent=None, standalone_items=None, are_names=False, is_symbol=False, item_needs_parens=None)

    Execute `print_node()` on all the nodes, separating them with sep.

    Parameters:

      - nodes – a sequence of `Node` instances

      - sep (str) – the separator between them

      - relative_indent (bool) – if given, the relative amount of indentation to apply before the first item, by default computed automatically from the length of the separator sep

      - standalone_items (bool) – whether a newline will be emitted before each item

      - are_names (bool) – whether the nodes are actually names, which possibly require to be enclosed between double-quotes

      - is_symbol (bool) – whether the nodes are actually a symbol such as an operator name, in which case the last one must be printed verbatim (e.g. `"MySchema".===`)

      - item_needs_parens – either `None` or a callable

  print_lists(lists, sep=',', relative_indent=None, standalone_items=None, are_names=False, sublist_open='(', sublist_close=')', sublist_sep=',', sublist_relative_indent=None)

    Execute `print_list()` on all the lists items.

    Parameters:

      - lists – a sequence of sequences of `Node` instances

      - sep (str) – passed as is to `print_list()`

      - relative_indent (bool) – passed as is to `print_list()`

      - standalone_items (bool) – passed as is to `print_list()`

      - are_names (bool) – passed as is to `print_list()`

      - sublist_open (str) – the string that will be emitted before each sublist

      - sublist_close (str) – the string that will be emitted after each sublist

      - sublist_sep (str) – the separator between them each sublist

      - sublist_relative_indent (bool) – if given, the relative amount of indentation to apply before the first sublist, by default computed automatically from the length of the separator sublist_sep

  print_name(nodes, sep='.')

    Helper method, execute `print_node()` or `print_list()` as needed.

  print_node(node, is_name=False, is_symbol=False)

    Lookup the specific printer for the given node and execute it.

    Parameters:

      - node – an instance of `Node`

      - is_name (bool) – whether this is a name of something, that may need to be double quoted

      - is_symbol (bool) – whether this is the name of an operator, should not be double quoted

  print_symbol(nodes, sep='.')

    Helper method, execute `print_node()` or `print_list()` as needed.

  push_indent(amount=0, relative=True)

    Create a no-op context manager, shall be overridden by the prettifier subclass.

  show(where=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>)

    Emit also current expression_level and a “pointer” showing current_column.

  space(count=1)

    Emit a single whitespace, shall be overridden by the prettifier subclass.

  write_quoted_string(s)

    Emit the string s as a single-quoted literal constant.

class pglast.stream.IndentedStream(compact_lists_margin=None, split_string_literals_threshold=None, **options)

  Indented SQL parse tree writer.

  Parameters:

    - compact_lists_margin (int) – an integer value that, if given, is used to print lists on a single line, when they do not exceed the given margin on the right

    - split_string_literals_threshold (int) – an integer value that, if given, is used as the threshold beyond that a string literal gets splitted in successive chunks of that length

    - **options – other options accepted by `RawStream`

  This augments `RawStream` to emit a prettified representation of a parse tree.

  dedent()

    Pop the indentation level from the stack and set current_indent to that.

  indent(amount=0, relative=True)

    Push current indentation level to the stack, then set it adding amount to the current_column if relative is `True` otherwise to current_indent.

  newline()

    Emit a newline.

  print_comment(comment)

    Print the given comment, unconditionally in the `C` syntax, joining all lines.

  print_list(nodes, sep=',', relative_indent=None, standalone_items=None, are_names=False, is_symbol=False, item_needs_parens=None)

    Execute `print_node()` on all the nodes, separating them with sep.

    Parameters:

      - nodes – a sequence of `Node` instances

      - sep (str) – the separator between them

      - relative_indent (bool) – if given, the relative amount of indentation to apply before the first item, by default computed automatically from the length of the separator sep

      - standalone_items (bool) – whether a newline will be emitted before each item

      - are_names (bool) – whether the nodes are actually names, which possibly require to be enclosed between double-quotes

      - is_symbol (bool) – whether the nodes are actually an operator name, in which case the last one must be printed verbatim (such as `"MySchema".===`)

      - item_needs_parens – either `None` or a callable

  push_indent(amount=0, relative=True)

    Create a context manager that calls `indent()` and `dedent()` around a block of code.

    This is just an helper to simplify code that adjusts the indentation level:

        with output.push_indent(4):
            # code that emits something with the new indentation

  show(where=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>)

    Emit also current_indent and indentation_stack.

  space(count=1)

    Emit consecutive spaces.

  write(s)

    Write string s to the stream, adjusting the current_column accordingly.

    Parameters:

      s (str) – the string to emit

    Returns:

      the number of characters written to the stream

    If s is a newline character (`\n`) set current_column to 0. Otherwise when current_column is 0 and current_indent is greater than 0 emit a number of whitespaces before emitting s, to indent it as expected.

  write_quoted_string(s)

    Emit the string s possibly splitted in successive chunks.

    When the `split_string_literals_threshold` option is greater than 0 and the length of s exceeds that value, split the string into multiple chunks.