]> granicus.if.org Git - pgbadger/commitdiff
Update SQL beautifier to v3.1 of pgFormatter.
authorGilles Darold <gilles@darold.net>
Wed, 12 Sep 2018 19:16:18 +0000 (21:16 +0200)
committerGilles Darold <gilles@darold.net>
Wed, 12 Sep 2018 19:16:18 +0000 (21:16 +0200)
pgbadger

index 71b01145ff75186ca015ec5c264ee2d920e0144f..4480cb19f04718f68bae04040d28a3c5f185fe17 100755 (executable)
--- a/pgbadger
+++ b/pgbadger
@@ -14954,7 +14954,6 @@ sub change_timezone
 
 # Inclusion of Perl package pgFormatter::Beautify.
 {
-
 package pgFormatter::Beautify;
 
 use strict;
@@ -14965,6 +14964,16 @@ use Encode qw( decode );
 # PostgreSQL functions that use a FROM clause
 our @have_from_clause = qw( extract overlay substring trim );
 
+=head1 NAME
+
+pgFormatter::Beautify - Library for pretty-printing SQL queries
+
+=head1 VERSION
+
+Version 3.0
+
+=cut
+
 # Version of pgFormatter
 our $VERSION = '3.0';
 
@@ -14972,6 +14981,107 @@ our $VERSION = '3.0';
 # Copyright (C) 2009 by Jonas Kramer
 # Published under the terms of the Artistic License 2.0.
 
+=head1 SYNOPSIS
+
+This module can be used to reformat given SQL query, optionally anonymizing parameters.
+
+Output can be either plain text, or it can be HTML with appropriate styles so that it can be displayed on a web page.
+
+Example usage:
+
+    my $beautifier = pgFormatter::Beautify->new();
+    $beautifier->query( 'select a,b,c from d where e = f' );
+
+    $beautifier->beautify();
+    my $nice_txt = $beautifier->content();
+
+    $beautifier->format('html');
+    $beautifier->beautify();
+    my $nice_html = $beautifier->content();
+
+    $beautifier->format('html');
+    $beautifier->anonymize();
+    $beautifier->beautify();
+    my $nice_anonymized_html = $beautifier->content();
+
+=head1 FUNCTIONS
+
+=head2 new
+
+Generic constructor - creates object, sets defaults, and reads config from given hash with options.
+
+Takes options as hash. Following options are recognized:
+
+=over
+
+=item * break - String that is used for linebreaks. Default is "\n".
+
+=item * colorize - if set to false CSS style will not be applied to html output. Used internally to display errors in CGI mode withour style.
+
+=item * comma - set comma at beginning or end of a line in a parameter list
+
+=over
+
+=item end - put comma at end of the list (default)
+
+=item start - put comma at beginning of the list
+
+=back
+
+=item * comma_break - add new-line after each comma in INSERT statements
+
+=item * format - set beautify format to apply to the content (default: text)
+
+=over
+
+=item text - output content as plain/text (command line mode default)
+
+=item html - output text/html with CSS style applied to content (CGI mode default)
+
+=back
+
+=item * functions - list (arrayref) of strings that are function names
+
+=item * keywords - list (arrayref) of strings that are keywords
+
+=item * no_comments - if set to true comments will be removed from query
+
+=item * placeholder - use the specified regex to find code that must not be changed in the query.
+
+=item * query - query to beautify
+
+=item * rules - hash of rules - uses rule semantics from SQL::Beautify
+
+=item * space - character(s) to be used as space for indentation
+
+=item * spaces - how many spaces to use for indentation
+
+=item * uc_functions - what to do with function names:
+
+=over
+
+=item 0 - do not change
+
+=item 1 - change to lower case
+
+=item 2 - change to upper case
+
+=item 3 - change to Capitalized
+
+=back
+
+=item * separator - string used as dynamic code separator, default is single quote.
+
+=item * uc_keywords - what to do with keywords - meaning of value like with uc_functions
+
+=item * wrap - wraps given keywords in pre- and post- markup. Specific docs in SQL::Beautify
+
+=back
+
+For defaults, please check function L<set_defaults>.
+
+=cut
+
 sub new {
     my $class   = shift;
     my %options = @_;
@@ -15008,15 +15118,63 @@ sub new {
     return $self;
 }
 
+=head2 query
+
+Accessor to query string. Both reads:
+
+    $object->query()
+
+, and writes
+
+    $object->query( $something )
+
+=cut
+
 sub query {
     my $self      = shift;
     my $new_value = shift;
 
     $self->{ 'query' } = $new_value if defined $new_value;
 
+    my $i = 0;
+    my %temp_placeholder = ();
+    my @temp_content = split(/(CREATE(?:\s+OR\s+REPLACE)?\s+(?:FUNCTION|PROCEDURE)\s+)/i, $self->{ 'query' });
+    if ($#temp_content > 0) {
+        for (my $j = 0; $j <= $#temp_content; $j++) {
+            next if ($temp_content[$j] =~ /^CREATE/i);
+            my $fctname = '';
+            if ($temp_content[$j] =~ /^([^\s\(]+)/) {
+                $fctname = lc($1);
+            }
+            next if (!$fctname);
+            my $language = 'sql';
+            if ($temp_content[$j] =~ /\s+LANGUAGE\s+[']*([^'\s;]+)[']*/i) {
+                $language = lc($1);
+            }
+            # if the function language is not SQL or PLPGSQL
+            if ($language !~ /^(?:plpg)sql$/) {
+                # Try to find the code separator
+                my $tmp_str = $temp_content[$j];
+                while ($tmp_str =~ s/\s+AS\s+([^\s]+)\s+//is) {
+                    my $code_sep = quotemeta($1);
+                   foreach my $k (@{ $self->{ 'keywords' } }) {
+                           last if ($code_sep =~ s/\b$k$//i); 
+                   }
+                    if ($tmp_str =~ /\s+$code_sep[\s;]+/) {
+                        while ( $temp_content[$j] =~ s/($code_sep.*$code_sep)/CODEPART${i}CODEPART/s) {
+                            push(@{ $self->{ 'placeholder_values' } }, $1);
+                            $i++;
+                        }
+                       last;
+                    }
+                }
+            }
+        }
+    }
+    $self->{ 'query' } = join('', @temp_content);
+
     # Store values of code that must not be changed following the given placeholder
     if ($self->{ 'placeholder' }) {
-        my $i = 0;
         while ( $self->{ 'query' } =~ s/($self->{ 'placeholder' })/PLACEHOLDER${i}PLACEHOLDER/) {
             push(@{ $self->{ 'placeholder_values' } }, $1);
             $i++;
@@ -15029,6 +15187,15 @@ sub query {
     return $self->{ 'query' };
 }
 
+=head2 content
+
+Accessor to content of results. Must be called after $object->beautify().
+
+This can be either plain text or html following the format asked by the
+client with the $object->format() method.
+
+=cut
+
 sub content {
     my $self      = shift;
     my $new_value = shift;
@@ -15045,13 +15212,21 @@ sub content {
     #$self->_restore_comments(\$self->{ 'content' });
 
     # Replace placeholders by their original values
-    if ($self->{ 'placeholder' }) {
+    if ($#{ $self->{ 'placeholder_values' } } >= 0)
+    {
         $self->{ 'content' } =~ s/PLACEHOLDER(\d+)PLACEHOLDER/$self->{ 'placeholder_values' }[$1]/igs;
+        $self->{ 'content' } =~ s/CODEPART(\d+)CODEPART/$self->{ 'placeholder_values' }[$1]/igs;
     }
 
     return $self->{ 'content' };
 }
 
+=head2 highlight_code
+
+Makes result html with styles set for highlighting.
+
+=cut
+
 sub highlight_code {
     my ($self, $token, $last_token, $next_token) = @_;
 
@@ -15063,62 +15238,62 @@ sub highlight_code {
     while ( my ( $k, $v ) = each %{ $self->{ 'dict' }->{ 'symbols' } } ) {
         if ($token eq $k) {
             $token = '<span class="sy0">' . $v . '</span>';
-           return $token;
-       }
+        return $token;
+    }
     }
 
     # lowercase/uppercase keywords
     if ( $self->_is_keyword( $token ) ) {
-       if ( $self->{ 'uc_keywords' } == 1 ) {
-               $token = '<span class="kw1_l">' . $token . '</span>';
-       } elsif ( $self->{ 'uc_keywords' } == 2 ) {
-               $token = '<span class="kw1_u">' . $token . '</span>';
-       } elsif ( $self->{ 'uc_keywords' } == 3 ) {
-               $token = '<span class="kw1_c">' . $token . '</span>';
-       } else {
-               $token = '<span class="kw1">' . $token . '</span>';
-       }
-       return $token;
+    if ( $self->{ 'uc_keywords' } == 1 ) {
+        $token = '<span class="kw1_l">' . $token . '</span>';
+    } elsif ( $self->{ 'uc_keywords' } == 2 ) {
+        $token = '<span class="kw1_u">' . $token . '</span>';
+    } elsif ( $self->{ 'uc_keywords' } == 3 ) {
+        $token = '<span class="kw1_c">' . $token . '</span>';
+    } else {
+        $token = '<span class="kw1">' . $token . '</span>';
+    }
+    return $token;
     }
 
     # lowercase/uppercase known functions or words followed by an open parenthesis if the token is not an open parenthesis
     if ($self->_is_function( $token ) || (!$self->_is_keyword( $token ) && $next_token eq '(' && $token ne '(' && !$self->_is_comment( $token )) ) {
-       if ($self->{ 'uc_functions' } == 1) {
-               $token = '<span class="kw2_l">' . $token . '</span>';
-       } elsif ($self->{ 'uc_functions' } == 2) {
-               $token = '<span class="kw2_u">' . $token . '</span>';
-       } elsif ($self->{ 'uc_functions' } == 3) {
-               $token = '<span class="kw2_c">' . $token . '</span>';
-       } else {
-               $token = '<span class="kw2">' . $token . '</span>';
-       }
-       return $token;
+    if ($self->{ 'uc_functions' } == 1) {
+        $token = '<span class="kw2_l">' . $token . '</span>';
+    } elsif ($self->{ 'uc_functions' } == 2) {
+        $token = '<span class="kw2_u">' . $token . '</span>';
+    } elsif ($self->{ 'uc_functions' } == 3) {
+        $token = '<span class="kw2_c">' . $token . '</span>';
+    } else {
+        $token = '<span class="kw2">' . $token . '</span>';
+    }
+    return $token;
     }
 
     # Colorize STDIN/STDOUT in COPY statement
     if ( grep(/^\Q$token\E$/i, @{ $self->{ 'dict' }->{ 'copy_keywords' } }) ) {
-       if ($self->{ 'uc_keywords' } == 1) {
-               $token = '<span class="kw3_!">' . $token . '</span>';
-       } elsif ($self->{ 'uc_keywords' } == 2) {
-               $token = '<span class="kw3_u">' . $token . '</span>';
-       } elsif ($self->{ 'uc_keywords' } == 3) {
-               $token = '<span class="kw3_c">' . $token . '</span>';
-       } else {
-               $token = '<span class="kw3">' . $token . '</span>';
-       }
-       return $token;
+    if ($self->{ 'uc_keywords' } == 1) {
+        $token = '<span class="kw3_!">' . $token . '</span>';
+    } elsif ($self->{ 'uc_keywords' } == 2) {
+        $token = '<span class="kw3_u">' . $token . '</span>';
+    } elsif ($self->{ 'uc_keywords' } == 3) {
+        $token = '<span class="kw3_c">' . $token . '</span>';
+    } else {
+        $token = '<span class="kw3">' . $token . '</span>';
+    }
+    return $token;
     }
 
     # Colorize parenthesis
     if ( grep(/^\Q$token\E$/i, @{ $self->{ 'dict' }->{ 'brackets' } }) ) {
         $token = '<span class="br0">' . $token . '</span>';
-       return $token;
+    return $token;
     }
 
     # Colorize comment
     if ( $self->_is_comment( $token ) ) {
         $token = '<span class="br1">' . $token . '</span>';
-       return $token;
+    return $token;
     }
 
     # Colorize numbers
@@ -15131,6 +15306,14 @@ sub highlight_code {
     return $token;
 }
 
+=head2 tokenize_sql
+
+Splits input SQL into tokens
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub tokenize_sql {
     my $self  = shift;
     my $query = $self->query();
@@ -15203,6 +15386,16 @@ sub tokenize_sql {
     return @query;
 }
 
+=head2 beautify
+
+Beautify SQL.
+
+After calling this function, $object->content() will contain nicely indented result.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub beautify {
     my $self = shift;
 
@@ -15242,21 +15435,21 @@ sub beautify {
     while ( defined( my $token = $self->_token ) ) {
         my $rule = $self->_get_rule( $token );
 
-       ####
-       # Find if the current keyword is a known function name
-       ####
+        ####
+        # Find if the current keyword is a known function name
+        ####
         if (defined $last && $last && defined $self->_next_token and $self->_next_token eq '(') {
-           my $word = $token;
-           $word =~ s/^[^\.]+\.//;
-           if ($word && grep(/^\Q$word\E$/i, @{$self->{ 'dict' }->{ 'pg_functions' }})) {
-               $self->{ '_is_in_function' }++;
-           }
+            my $word = $token;
+            $word =~ s/^[^\.]+\.//;
+            if ($word && grep(/^\Q$word\E$/i, @{$self->{ 'dict' }->{ 'pg_functions' }})) {
+                $self->{ '_is_in_function' }++;
+            }
         }
 
-       ####
+        ####
         # Set open parenthesis position to know if we
-       # are in subqueries or function parameters
-       ####
+        # are in subqueries or function parameters
+        ####
         if ( $token eq ')')
         {
             if (!$self->{ '_is_in_function' }) {
@@ -15278,71 +15471,74 @@ sub beautify {
             }
         }
 
-       ####
-       # Control case where we have to add a newline, go back and
-       # reset indentation after the last ) in the WITH statement
-       ####
-       if ($token =~ /^WITH$/i && (!defined $last || $last ne ')')) {
+        ####
+        # Control case where we have to add a newline, go back and
+        # reset indentation after the last ) in the WITH statement
+        ####
+        if ($token =~ /^WITH$/i && (!defined $last || $last ne ')'))
+       {
             $self->{ '_is_in_with' } = 1;
         }
-        elsif ($token =~ /^(AS|IS)$/i && defined $self->_next_token && $self->_next_token eq '(') {
+        elsif ($token =~ /^(AS|IS)$/i && defined $self->_next_token && $self->_next_token eq '(')
+       {
             $self->{ '_is_in_with' }++ if ($self->{ '_is_in_with' } == 1);
         }
-       elsif ( $token eq ')' ) {
-           $self->{ '_has_order_by' } = 0;
+        elsif ( $token eq ')' )
+       {
+            $self->{ '_has_order_by' } = 0;
             $self->{ '_has_from' } = 0;
             if ($self->{ '_is_in_with' } > 1 && !$self->{ '_parenthesis_level' }) {
-               $self->_new_line;
+                $self->_new_line;
                 $self->_back;
                 $self->_add_token( $token );
                 @{ $self->{ '_level_stack' } } = ();
                 $self->{ '_level' } = 0;
                 $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
-               if ($self->{ '_is_in_with' }) {
-                   if (defined $self->_next_token && $self->_next_token eq ',') {
-                       $self->{ '_is_in_with' } = 1;
-                   } else {
-                       $self->{ '_is_in_with' } = 0;
-                   }
-               }
-               next;
+                if ($self->{ '_is_in_with' }) {
+                    if (defined $self->_next_token && $self->_next_token eq ',') {
+                        $self->{ '_is_in_with' } = 1;
+                    } else {
+                        $self->{ '_is_in_with' } = 0;
+                    }
+                }
+                next;
             }
-       }
+        }
 
-       ####
-       # Set the current kind of statement parsed
-       ####
+        ####
+        # Set the current kind of statement parsed
+        ####
         if ($token =~ /^(FUNCTION|PROCEDURE|SEQUENCE|INSERT|DELETE|UPDATE|SELECT|RAISE|ALTER|GRANT|REVOKE)$/i) {
-           my $k_stmt = uc($1);
-           # Set current statement with taking care to exclude of SELECT ... FOR UPDATE statement.
+            my $k_stmt = uc($1);
+            # Set current statement with taking care to exclude of SELECT ... FOR UPDATE statement.
             if ($k_stmt ne 'UPDATE' or (defined $self->_next_token and $self->_next_token ne ';' and $self->_next_token ne ')')) {
                 $self->{ '_current_sql_stmt' } = $k_stmt if ($self->{ '_current_sql_stmt' } !~ /^(GRANT|REVOKE)$/i);
-           }
+            }
         }
 
-       ####
-       # Mark that we are in CREATE statement that need newline
-       # after a comma in the parameter, declare or column lists.
-       ####
+        ####
+        # Mark that we are in CREATE statement that need newline
+        # after a comma in the parameter, declare or column lists.
+        ####
         if ($token =~ /^CREATE$/i && $self->_next_token !~ /^(UNIQUE|INDEX|EXTENSION|TYPE)$/i) {
             $self->{ '_is_in_create' } = 1;
         } elsif ($token =~ /^CREATE$/i && $self->_next_token =~ /^TYPE$/i) {
             $self->{ '_is_in_type' } = 1;
         }
 
-       ####
-       # Mark that we are in index/constraint creation statement to
-       # avoid inserting a newline after comma and AND/OR keywords.
+        ####
+        # Mark that we are in index/constraint creation statement to
+        # avoid inserting a newline after comma and AND/OR keywords.
         # This also used in SET statement taking care that we are not
-       # in update statement. CREATE statement are not subject to this rule
-       ####
+        # in update statement. CREATE statement are not subject to this rule
+        ####
         if (! $self->{ '_is_in_create' } and $token =~ /^(INDEX|PRIMARY|CONSTRAINT)$/i) {
             $self->{ '_is_in_index' } = 1;
         } elsif (! $self->{ '_is_in_create' } and uc($token) eq 'SET') {
             $self->{ '_is_in_index' } = 1 if ($self->{ '_current_sql_stmt' } ne 'UPDATE');
         }
         # Same as above but for ALTER FUNCTION/PROCEDURE/SEQUENCE or when
-       # we are in a CREATE FUNCTION/PROCEDURE statement
+        # we are in a CREATE FUNCTION/PROCEDURE statement
         elsif ($token =~ /^(FUNCTION|PROCEDURE|SEQUENCE)$/i) {
             $self->{ '_is_in_index' } = 1 if (uc($last) eq 'ALTER');
             if ($token =~ /^(FUNCTION|PROCEDURE)$/i && $self->{ '_is_in_create' }) {
@@ -15352,56 +15548,70 @@ sub beautify {
         # Desactivate index like formatting when RETURN(S) keyword is found
         elsif ($token =~ /^(RETURN|RETURNS)$/i) {
             $self->{ '_is_in_index' } = 0;
-       }
-
-       ####
-       # Mark statements that use string_agg() or group_concat() function
-       # as statement that can have an ORDER BY clause inside the call to
-       # prevent applying order by formatting.
-       ####
-       if ($token =~ /^(string_agg|group_concat)$/i) {
-           $self->{ '_has_order_by' } = 1;
+        }
+    
+        ####
+        # Mark statements that use string_agg() or group_concat() function
+        # as statement that can have an ORDER BY clause inside the call to
+        # prevent applying order by formatting.
+        ####
+        if ($token =~ /^(string_agg|group_concat)$/i) {
+            $self->{ '_has_order_by' } = 1;
         } elsif ( $self->{ '_has_order_by' } and uc($token) eq 'ORDER' and $self->_next_token =~ /^BY$/i) {
-           $self->_add_token( $token );
+            $self->_add_token( $token );
             $last = $token;
             next;
         } elsif ($self->{ '_has_order_by' } and uc($token) eq 'BY') {
-           $self->_add_token( $token );
+            $self->_add_token( $token );
             $self->{ '_has_order_by' } = 0;
             next;
         }
 
-       ####
-       # Set function code delimiter, it can be any string found after
-       # the AS keyword in function or procedure creation code
-       ####
+        ####
+        # Set function code delimiter, it can be any string found after
+        # the AS keyword in function or procedure creation code
+        ####
         # Toogle _fct_code_delimiter to force next token to be stored as the function code delimiter
-        if (uc($token) eq 'AS' and !$self->{ '_fct_code_delimiter' }
-               and $self->{ '_current_sql_stmt' } =~ /^(FUNCTION|PROCEDURE)$/i) {
-
-            if ($self->{ '_is_in_create' }) {
+        if (uc($token) eq 'AS' and (!$self->{ '_fct_code_delimiter' } || $self->_next_token =~ /CODEPART/)
+                               and $self->{ '_current_sql_stmt' } =~ /^(FUNCTION|PROCEDURE)$/i)
+        {
+            if ($self->{ '_is_in_create' })
+           {
                 $self->_new_line;
-                @{ $self->{ '_level_stack' } } = ();
-                $self->{ '_level' } = 0;
-                $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
+                $self->_add_token( $token );
+               @{ $self->{ '_level_stack' } } = ();
+               $self->{ '_level' } = 0;
+               $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
                 $self->{ '_is_in_create' } = 0;
+           } else {
+                $self->_add_token( $token );
             }
-            $self->{ '_fct_code_delimiter' } = '1';
+           if ($self->_next_token !~ /CODEPART/)
+           {
+                $self->{ '_fct_code_delimiter' } = '1';
+           }
             $self->{ '_is_in_create' } = 0;
-            $self->_add_token( $token );
             next;
         }
+
         # Store function code delimiter
-        if ($self->{ '_fct_code_delimiter' } eq '1') {
-            $self->{ '_fct_code_delimiter' } = $token;
+        if ($self->{ '_fct_code_delimiter' } eq '1')
+       {
+           if ($self->_next_token =~ /CODEPART/) {
+                $self->{ '_fct_code_delimiter' } = '0';
+           } else {
+               $self->{ '_fct_code_delimiter' } = $token;
+           }
             $self->_add_token( $token );
             $last = $token;
             $self->_new_line;
             $self->_over if (defined $self->_next_token && $self->_next_token !~ /^(DECLARE|BEGIN)$/i);
             next;
         }
+
         # Desactivate the block mode when code delimiter is found for the second time
-        if ($self->{ '_fct_code_delimiter' } && $token eq $self->{ '_fct_code_delimiter' }) {
+        if ($self->{ '_fct_code_delimiter' } && $token eq $self->{ '_fct_code_delimiter' })
+       {
             $self->{ '_is_in_block' } = -1;
             @{ $self->{ '_level_stack' } } = ();
             $self->{ '_level' } = 0;
@@ -15413,20 +15623,24 @@ sub beautify {
             next;
         }
 
-       ####
-       # Mark when we are parsing a DECLARE or a BLOCK section. When
-       # entering a BLOCK section store the current indentation level
-       ####
+        ####
+        # Mark when we are parsing a DECLARE or a BLOCK section. When
+        # entering a BLOCK section store the current indentation level
+        ####
         if (uc($token) eq 'DECLARE') {
             $self->{ '_is_in_block' } = -1;
             $self->{ '_is_in_declare' } = 1;
+            @{ $self->{ '_level_stack' } } = ();
+            $self->{ '_level' } = 0;
+            $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
             $self->_new_line;
             $self->_add_token( $token );
             $self->_new_line;
             $self->_over;
-           next;
-       }
-        elsif ( uc($token) eq 'BEGIN' ) {
+            next;
+        }
+        elsif ( uc($token) eq 'BEGIN' )
+       {
             $self->{ '_is_in_declare' } = 0;
             if ($self->{ '_is_in_block' } == -1) {
                 @{ $self->{ '_level_stack' } } = ();
@@ -15443,41 +15657,47 @@ sub beautify {
                 $self->_over;
                 $self->{ '_is_in_block' }++;
             }
-           next;
+            next;
         }
 
-       ####
-       # Special case where we want to add a newline into ) AS (
-       ####
-        if (uc($token) eq 'AS' and $last eq ')' and $self->_next_token eq '(') {
+        ####
+        # Special case where we want to add a newline into ) AS (
+        ####
+        if (uc($token) eq 'AS' and $last eq ')' and $self->_next_token eq '(')
+       {
             $self->_new_line;
-       # and before RETURNS with increasing indent level
-        } elsif (uc($token) eq 'RETURNS') {
+        }
+        # and before RETURNS with increasing indent level
+       elsif (uc($token) eq 'RETURNS')
+       {
             $self->_new_line;
             $self->_over;
         }
 
-        if ( $rule ) {
+        if ( $rule )
+       {
             $self->_process_rule( $rule, $token );
         }
 
-        elsif ($token =~ /^(LANGUAGE|SECURITY|)$/i) {
+        elsif ($token =~ /^(LANGUAGE|SECURITY|COST)$/i)
+       {
             $self->_new_line;
             $self->_add_token( $token );
         }
 
-        elsif ( $token eq '(' ) {
+        elsif ( $token eq '(' )
+       {
             $self->{ '_is_in_create' }++ if ($self->{ '_is_in_create' });
             $self->_add_token( $token, $last );
             if ( !$self->{ '_is_in_index' }) {
                 if (uc($last) eq 'AS' || $self->{ '_is_in_create' } == 2 || uc($self->_next_token) eq 'CASE') {
                     $self->_new_line;
                 }
-               if ($self->{ '_is_in_with' } == 1) {
+                if ($self->{ '_is_in_with' } == 1) {
                     $self->_over;
                     $self->_new_line;
                     next;
-               }
+                }
                 $self->_over;
                 if ($self->{ '_is_in_type' } == 1) {
                     $last = $token;
@@ -15487,12 +15707,12 @@ sub beautify {
         }
 
         elsif ( $token eq ')' ) {
-           if ($self->{ '_is_in_with' } == 1) {
+            if ($self->{ '_is_in_with' } == 1) {
                 $self->_back;
                 $self->_new_line;
                 $self->_add_token( $token );
                 next;
-           }
+            }
             if ($self->{ '_is_in_index' }) {
                 $self->_add_token( '' );
                 $self->_add_token( $token );
@@ -15507,7 +15727,12 @@ sub beautify {
                 );
             $self->{ '_is_in_create' }-- if ($self->{ '_is_in_create' });
             $self->{ '_is_in_type' }-- if ($self->{ '_is_in_type' });
-            $self->_new_line if ($self->{ '_current_sql_stmt' } ne 'INSERT' and !$self->{ '_is_in_function' } and (defined $self->_next_token and $self->_next_token =~ /^(SELECT|WITH)$/i) and $last ne ')');
+            $self->_new_line if ($self->{ '_current_sql_stmt' } ne 'INSERT'
+                           and !$self->{ '_is_in_function' }
+                           and (defined $self->_next_token 
+                                   and $self->_next_token =~ /^(SELECT|WITH)$/i)
+                           and $last ne ')'
+           );
             $self->_back;
             $self->_add_token( $token );
             # Do not go further if this is the last token
@@ -15524,7 +15749,7 @@ sub beautify {
                 my $next_tok = quotemeta($self->_next_token);
                 $self->_new_line
                     if (defined $self->_next_token
-                    and $self->_next_token !~ /^AS|THEN|INTO|BETWEEN$/i
+                    and $self->_next_token !~ /^AS|THEN|INTO|BETWEEN|ON$/i
                     and ($self->_next_token !~ /^AND|OR$/i or !$self->{ '_is_in_if' })
                     and $self->_next_token ne ')'
                     and $self->_next_token !~ /^:/
@@ -15543,12 +15768,13 @@ sub beautify {
                                && !$self->{ '_is_in_function' }
                                && ($self->{ 'comma_break' } || $self->{ '_current_sql_stmt' } ne 'INSERT')
                                && ($self->{ '_current_sql_stmt' } ne 'RAISE')
-                               && ($self->{ '_current_sql_stmt' } !~ /^FUNCTION|PROCEDURE$/ || $self->{ '_fct_code_delimiter' } ne '')
+                               && ($self->{ '_current_sql_stmt' } !~ /^FUNCTION|PROCEDURE$/
+                                      || $self->{ '_fct_code_delimiter' } ne '')
                                && !$self->{ '_is_in_where' }
                                && !$self->{ '_is_in_index' }
                                && $self->{ '_current_sql_stmt' } !~ /^(GRANT|REVOKE)$/
                                && $self->_next_token !~ /^('$|\-\-)/i
-                              && !$self->{ '_parenthesis_function_level' }
+                   && !$self->{ '_parenthesis_function_level' }
                     );
 
             if ($self->{ '_is_in_with' } >= 1 && !$self->{ '_parenthesis_level' }) {
@@ -15560,11 +15786,11 @@ sub beautify {
         }
 
         elsif ( $token eq ';' or $token =~ /^\\(?:g|crosstabview|watch)/ ) { # statement separator or executing psql meta command (prefix 'g' includes all its variants)
-           # Initialize most of statement related variables
+            # Initialize most of statement related variables
             $self->{ '_has_from' } = 0;
             $self->{ '_is_in_where' } = 0;
             $self->{ '_is_in_from' } = 0;
-           $self->{ '_is_in_join' } = 0;
+            $self->{ '_is_in_join' } = 0;
             $self->{ '_is_in_create' } = 0;
             $self->{ '_is_in_type' } = 0;
             $self->{ '_is_in_function' } = 0;
@@ -15572,24 +15798,28 @@ sub beautify {
             $self->{ '_is_in_if' } = 0;
             $self->{ '_current_sql_stmt' } = '';
             $self->{ '_is_in_with' } = 0;
-           $self->{ '_has_order_by' } = 0;
+            $self->{ '_has_order_by' } = 0;
             $self->{ '_has_over_in_join' } = 0;
             $self->{ '_parenthesis_level' } = 0;
-           $self->{ '_parenthesis_function_level' } = 0;
+            $self->{ '_parenthesis_function_level' } = 0;
             $self->_add_token($token);
             $self->{ 'break' } = "\n" unless ( $self->{ 'spaces' } != 0 );
             $self->_new_line;
             # Add an additional newline after ; when we are not in a function
-            if ($self->{ '_is_in_block' } == -1 and !$self->{ '_is_in_declare' } and !$self->{ '_fct_code_delimiter' }) {
+            if ($self->{ '_is_in_block' } == -1 and !$self->{ '_is_in_declare' } and !$self->{ '_fct_code_delimiter' })
+           {
                 $self->{ '_new_line' } = 0;
                 $self->_new_line;
             }
             # End of statement; remove all indentation when we are not in a BEGIN/END block
-            if (!$self->{ '_is_in_declare' } && $self->{ '_is_in_block' } == -1) {
+            if (!$self->{ '_is_in_declare' } && $self->{ '_is_in_block' } == -1)
+           {
                 @{ $self->{ '_level_stack' } } = ();
                 $self->{ '_level' } = 0;
                 $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
-            } else {
+            }
+           else
+           {
                 if ($#{ $self->{ '_level_stack' } } == -1) {
                         $self->{ '_level' } = ($self->{ '_is_in_declare' }) ? 1 : ($self->{ '_is_in_block' }+1);
                 } else {
@@ -15597,76 +15827,101 @@ sub beautify {
                 }
             }
         }
-        elsif ($token =~ /^FOR$/i) {
-            if ($self->_next_token =~ /^(UPDATE|KEY|NO)$/i) {
+        elsif ($token =~ /^FOR$/i)
+       {
+            if ($self->_next_token =~ /^(UPDATE|KEY|NO)$/i)
+           {
                 $self->_back;
                 $self->_new_line;
             }
             $self->_add_token( $token );
-            if ($self->_next_token =~ /^SELECT$/i) {
+            if ($self->_next_token =~ /^SELECT$/i)
+           {
                 $self->_new_line;
                 $self->_over;
             }
         }
 
-        elsif ( $token =~ /^(?:FROM|WHERE|SET|RETURNING|HAVING|VALUES)$/i ) {
+        elsif ( $token =~ /^(?:FROM|WHERE|SET|RETURNING|HAVING|VALUES)$/i )
+       {
 
             $self->{ 'no_break' } = 0;
 
-            if (uc($last) eq 'DISTINCT' and $token =~ /^FROM$/i) {
+            if (uc($last) eq 'DISTINCT' and $token =~ /^FROM$/i)
+           {
                 $self->_add_token( $token );
                 $last = $token;
                 next;
             }
-            if (($token =~ /^FROM$/i) && $self->{ '_has_from' } && !$self->{ '_is_in_function' }) {
+            if (($token =~ /^FROM$/i) && $self->{ '_has_from' } && !$self->{ '_is_in_function' })
+           {
                 $self->{ '_has_from' } = 0;
             }
-            if ($token =~ /^FROM$/i) {
+            if ($token =~ /^FROM$/i)
+           {
                 $self->{ '_is_in_from' }++ if (!$self->{ '_is_in_function' });
             }
-            if ($token =~ /^WHERE$/i) {
-               $self->_back() if ($self->{ '_has_over_in_join' });
+            if ($token =~ /^WHERE$/i)
+           {
+                $self->_back() if ($self->{ '_has_over_in_join' });
                 $self->{ '_is_in_where' }++;
                 $self->{ '_is_in_from' }-- if ($self->{ '_is_in_from' });
-               $self->{ '_is_in_join' } = 0;
-               $self->{ '_has_over_in_join' } = 0;
-            } elsif (!$self->{ '_is_in_function' }) {
+                $self->{ '_is_in_join' } = 0;
+                $self->{ '_has_over_in_join' } = 0;
+            }
+           elsif (!$self->{ '_is_in_function' })
+           {
                 $self->{ '_is_in_where' }-- if ($self->{ '_is_in_where' });
             }
 
-            if ($token =~ /^SET$/i and $self->{ '_is_in_create' }) {
+            if ($token =~ /^SET$/i and $self->{ '_is_in_create' })
+           {
                 # Add newline before SET statement in function header
                 $self->_new_line;
-            } elsif ($token =~ /^WHERE$/i and $self->{ '_current_sql_stmt' } eq 'DELETE') {
+            }
+           elsif ($token =~ /^WHERE$/i and $self->{ '_current_sql_stmt' } eq 'DELETE')
+           {
                 $self->_new_line;
                 $self->_add_token( $token );
                 $self->_over;
                 $last = $token;
-               $self->{ '_is_in_join' } = 0;
+                $self->{ '_is_in_join' } = 0;
                 next;
-            } elsif ($token !~ /^FROM$/i or (!$self->{ '_is_in_function' } and $self->{ '_current_sql_stmt' } ne 'DELETE')) {
-                if ($token !~ /^SET$/i or !$self->{ '_is_in_index' }) {
+            }
+           elsif ($token !~ /^FROM$/i or (!$self->{ '_is_in_function' }
+                                   and $self->{ '_current_sql_stmt' } ne 'DELETE'))
+           {
+                if ($token !~ /^SET$/i or !$self->{ '_is_in_index' })
+               {
                     $self->_back;
                     $self->_new_line;
                 }
-            } else {
+            }
+           else
+           {
                 $self->_add_token( $token );
                 $last = $token;
                 next;
             }
-            if ($token =~ /^VALUES$/i and ($self->{ '_current_sql_stmt' } eq 'INSERT' or $last eq '(')) {
+            if ($token =~ /^VALUES$/i and ($self->{ '_current_sql_stmt' } eq 'INSERT' or $last eq '('))
+           {
                 $self->_over;
             }
             $self->_add_token( $token );
-            if ($token =~ /^VALUES$/i and $last eq '(') {
+            if ($token =~ /^VALUES$/i and $last eq '(')
+           {
                 $self->_over;
             }
-            elsif ( $token =~ /^SET$/i && $self->{ '_current_sql_stmt' } eq 'UPDATE' ) {
+            elsif ( $token =~ /^SET$/i && $self->{ '_current_sql_stmt' } eq 'UPDATE' )
+           {
                     $self->_new_line;
                     $self->_over;
             }
-            elsif ( $token !~ /^SET$/i || $self->{ '_current_sql_stmt' } eq 'UPDATE' ) {
-                if (defined $self->_next_token and $self->_next_token ne '(' and ($self->_next_token !~ /^(UPDATE|KEY|NO)$/i || uc($token) eq 'WHERE')) {
+            elsif ( $token !~ /^SET$/i || $self->{ '_current_sql_stmt' } eq 'UPDATE' )
+           {
+                if (defined $self->_next_token and $self->_next_token ne '('
+                               and ($self->_next_token !~ /^(UPDATE|KEY|NO)$/i || uc($token) eq 'WHERE'))
+               {
                     $self->_new_line;
                     $self->_over;
                 }
@@ -15674,28 +15929,37 @@ sub beautify {
         }
 
         # Add newline before INSERT and DELETE if last token was AS (prepared statement)
-        elsif (defined $last and $token =~ /^INSERT|DELETE$/i and uc($last) eq 'AS') {
+        elsif (defined $last and $token =~ /^INSERT|DELETE$/i and uc($last) eq 'AS')
+       {
                 $self->_new_line;
                 $self->_add_token( $token );
         }
 
-        elsif ( $self->{ '_current_sql_stmt' } !~ /^(GRANT|REVOKE)$/ and $token =~ /^(?:SELECT|PERFORM|UPDATE|DELETE)$/i ) {
+        elsif ( $self->{ '_current_sql_stmt' } !~ /^(GRANT|REVOKE)$/
+                       and $token =~ /^(?:SELECT|PERFORM|UPDATE|DELETE)$/i )
+       {
             $self->{ 'no_break' } = 0;
 
-            if ($token =~ /^UPDATE$/i and $last =~ /^(FOR|KEY)$/i) {
+            if ($token =~ /^UPDATE$/i and $last =~ /^(FOR|KEY)$/i)
+           {
                 $self->_add_token( $token );
-            } elsif ($token !~ /^DELETE$/i) {
+            }
+           elsif ($token !~ /^DELETE$/i)
+           {
                 $self->_new_line;
                 $self->_add_token( $token );
                 $self->_new_line;
                 $self->_over;
-            } else {
+            }
+           else
+           {
                 $self->_add_token( $token );
             }
         }
 
-        elsif ( $token =~ /^(?:GROUP|ORDER|LIMIT|EXCEPTION)$/i ) {
-           $self->{ '_is_in_join' } = 0;
+        elsif ( $token =~ /^(?:GROUP|ORDER|LIMIT|EXCEPTION)$/i )
+       {
+            $self->{ '_is_in_join' } = 0;
             if ($token !~ /^EXCEPTION$/i) {
                 $self->_back;
             } else {
@@ -15704,20 +15968,23 @@ sub beautify {
             $self->_new_line;
             $self->_add_token( $token );
             # Store current indent position to print END at the right level
-            if ($token =~ /^EXCEPTION$/i) {
+            if ($token =~ /^EXCEPTION$/i)
+           {
                 push @{ $self->{ '_level_stack' } }, $self->{ '_level' };
                 $self->_over;
             }
             $self->{ '_is_in_where' }-- if ($self->{ '_is_in_where' });
         }
 
-        elsif ( $token =~ /^(?:BY)$/i and $last !~ /^(INCREMENT|OWNED)$/ ) {
+        elsif ( $token =~ /^(?:BY)$/i and $last !~ /^(INCREMENT|OWNED)$/ )
+       {
             $self->_add_token( $token );
             $self->_new_line;
             $self->_over;
         }
 
-        elsif ( $token =~ /^(?:CASE)$/i ) {
+        elsif ( $token =~ /^(?:CASE)$/i )
+       {
             $self->_add_token( $token );
             # Store current indent position to print END at the right level
             push @{ $self->{ '_level_stack' } }, $self->{ '_level' };
@@ -15727,7 +15994,8 @@ sub beautify {
             $self->{ '_is_in_case' }++;
         }
 
-        elsif ( $token =~ /^(?:WHEN)$/i ) {
+        elsif ( $token =~ /^(?:WHEN)$/i )
+       {
             $self->_back if (!$self->{ '_first_when_in_case' } and defined $last and uc($last) ne 'CASE');
             $self->_new_line if (not defined $last or uc($last) ne 'CASE');
             $self->_add_token( $token );
@@ -15735,9 +16003,11 @@ sub beautify {
             $self->{ '_first_when_in_case' } = 0;
         }
 
-        elsif ( $token =~ /^(?:IF|LOOP)$/i ) {
+        elsif ( $token =~ /^(?:IF|LOOP)$/i )
+       {
             $self->_add_token( $token );
-            if (defined $self->_next_token and $self->_next_token ne ';') {
+            if (defined $self->_next_token and $self->_next_token ne ';')
+           {
                 $self->_new_line if ($token =~ /^LOOP$/i);
                 $self->_over;
                 push @{ $self->{ '_level_stack' } }, $self->{ '_level' };
@@ -15747,13 +16017,15 @@ sub beautify {
             }
         }
 
-        elsif ($token =~ /^THEN$/i) {
+        elsif ($token =~ /^THEN$/i)
+       {
             $self->_add_token( $token );
             $self->_new_line;
             $self->{ '_is_in_if' } = 0;
         }
 
-        elsif ( $token =~ /^(?:ELSE|ELSIF)$/i ) {
+        elsif ( $token =~ /^(?:ELSE|ELSIF)$/i )
+       {
             $self->_back;
             $self->_new_line;
             $self->_add_token( $token );
@@ -15761,27 +16033,36 @@ sub beautify {
             $self->_over;
         }
 
-        elsif ( $token =~ /^(?:END)$/i ) {
+        elsif ( $token =~ /^(?:END)$/i )
+       {
             $self->{ '_first_when_in_case' } = 0;
-           if ($self->{ '_is_in_case' }) {
-               $self->{ '_is_in_case' }--;
-               $self->_back;
-           }
+            if ($self->{ '_is_in_case' })
+           {
+                $self->{ '_is_in_case' }--;
+                $self->_back;
+            }
             # When we are not in a function code block (0 is the main begin/end block of a function)
-            elsif ($self->{ '_is_in_block' } == -1) {
+            elsif ($self->{ '_is_in_block' } == -1)
+           {
                 # END is closing a create function statement so reset position to begining
-                if ($self->_next_token !~ /^(IF|LOOP|CASE|INTO|FROM|END|ELSE|AND|OR|WHEN|AS|,)$/i) {
+                if ($self->_next_token !~ /^(IF|LOOP|CASE|INTO|FROM|END|ELSE|AND|OR|WHEN|AS|,)$/i)
+               {
                     @{ $self->{ '_level_stack' } } = ();
                     $self->{ '_level' } = 0;
                     $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
-                } else {
+                }
+               else
+               {
                     # otherwise back to last level stored at CASE keyword
                     $self->{ '_level' } = pop( @{ $self->{ '_level_stack' } } ) || 0;
                 }
             # We are in code block
-            } else {
+            }
+           else
+           {
                 # decrease the block level if this is a END closing a BEGIN block
-                if ($self->_next_token !~ /^(IF|LOOP|CASE|INTO|FROM|END|ELSE|AND|OR|WHEN|AS|,)$/i) {
+                if ($self->_next_token !~ /^(IF|LOOP|CASE|INTO|FROM|END|ELSE|AND|OR|WHEN|AS|,)$/i)
+               {
                     $self->{ '_is_in_block' }--;
                 }
                 # Go back to level stored with IF/LOOP/BEGIN/EXCEPTION block
@@ -15792,83 +16073,106 @@ sub beautify {
             $self->_add_token( $token );
         }
 
-        elsif ( $token =~ /^(?:UNION|INTERSECT|EXCEPT)$/i ) {
+        elsif ( $token =~ /^(?:UNION|INTERSECT|EXCEPT)$/i )
+       {
             $self->{ 'no_break' } = 0;
-           if ($self->{ '_is_in_join' }) {
-               $self->_back;
-               $self->{ '_is_in_join' } = 0;
-           }
-           $self->_back unless defined $last and $last eq '(';
+            if ($self->{ '_is_in_join' })
+           {
+                $self->_back;
+                $self->{ '_is_in_join' } = 0;
+            }
+            $self->_back unless defined $last and $last eq '(';
             $self->_new_line;
             $self->_add_token( $token );
-            $self->_new_line if ( defined $self->_next_token and $self->_next_token ne '(' and $self->_next_token !~ /^ALL$/i );
+            $self->_new_line if ( defined $self->_next_token
+                           and $self->_next_token ne '('
+                           and $self->_next_token !~ /^ALL$/i
+           );
             $self->{ '_is_in_where' }-- if ($self->{ '_is_in_where' });
-           $self->{ '_is_in_from' } = 0;
+            $self->{ '_is_in_from' } = 0;
         }
 
-        elsif ( $token =~ /^(?:LEFT|RIGHT|FULL|INNER|OUTER|CROSS|NATURAL)$/i ) {
+        elsif ( $token =~ /^(?:LEFT|RIGHT|FULL|INNER|OUTER|CROSS|NATURAL)$/i )
+       {
             $self->{ 'no_break' } = 0;
-           if (!$self->{ '_is_in_join' } and ($last and $last ne ')') ) {
-               $self->_back;
-           }
-           if ($self->{ '_has_over_in_join' }) {
-               $self->{ '_has_over_in_join' } = 0;
-               $self->_back;
-           }
+            if (!$self->{ '_is_in_join' } and ($last and $last ne ')') )
+           {
+                $self->_back;
+            }
+            if ($self->{ '_has_over_in_join' })
+           {
+                $self->{ '_has_over_in_join' } = 0;
+                $self->_back;
+            }
 
-            if ( $token =~ /(?:LEFT|RIGHT|FULL|CROSS|NATURAL)$/i ) {
+            if ( $token =~ /(?:LEFT|RIGHT|FULL|CROSS|NATURAL)$/i )
+           {
                 $self->_new_line;
-               $self->_over if ( $self->{ '_level' } == 0 );
+                $self->_over if ( $self->{ '_level' } == 0 );
             }
-            if ( ($token =~ /(?:INNER|OUTER)$/i) && ($last !~ /(?:LEFT|RIGHT|CROSS|NATURAL|FULL)$/i) ) {
+            if ( ($token =~ /(?:INNER|OUTER)$/i) && ($last !~ /(?:LEFT|RIGHT|CROSS|NATURAL|FULL)$/i) )
+           {
                 $self->_new_line;
                 $self->_over if (!$self->{ '_is_in_join' });
             } 
             $self->_add_token( $token );
         }
 
-        elsif ( $token =~ /^(?:JOIN)$/i ) {
+        elsif ( $token =~ /^(?:JOIN)$/i )
+       {
             $self->{ 'no_break' } = 0;
-            if ( not defined $last or $last !~ /^(?:LEFT|RIGHT|FULL|INNER|OUTER|CROSS|NATURAL)$/i ) {
+            if ( not defined $last or $last !~ /^(?:LEFT|RIGHT|FULL|INNER|OUTER|CROSS|NATURAL)$/i )
+           {
                 $self->_new_line;
-               $self->_back if ($self->{ '_has_over_in_join' });
-               $self->{ '_has_over_in_join' } = 0;
+                $self->_back if ($self->{ '_has_over_in_join' });
+                $self->{ '_has_over_in_join' } = 0;
             }
             $self->_add_token( $token );
-           $self->{ '_is_in_join' } = 1;
+            $self->{ '_is_in_join' } = 1;
         }
 
-        elsif ( $token =~ /^(?:AND|OR)$/i ) {
-           # Try to detect AND in BETWEEN clause to prevent newline insert
-            if (uc($token) eq 'AND' and $self->_next_token() =~ /^\d+$/){
-               $self->_add_token( $token );
-               next;
-           }
+        elsif ( $token =~ /^(?:AND|OR)$/i )
+       {
+            # Try to detect AND in BETWEEN clause to prevent newline insert
+            if (uc($token) eq 'AND' and $self->_next_token() =~ /^\d+$/)
+           {
+                $self->_add_token( $token );
+                next;
+            }
             $self->{ 'no_break' } = 0;
-            if ($self->{ '_is_in_join' }) {
-               $self->_over;
-               $self->{ '_has_over_in_join' } = 1;
-           }
-           $self->{ '_is_in_join' } = 0;
-            if ( !$self->{ '_is_in_if' } and !$self->{ '_is_in_index' } and (!$last or $last !~ /^(?:CREATE)$/i) ) {
+            if ($self->{ '_is_in_join' })
+           {
+                $self->_over;
+                $self->{ '_has_over_in_join' } = 1;
+            }
+            $self->{ '_is_in_join' } = 0;
+            if ( !$self->{ '_is_in_if' } and !$self->{ '_is_in_index' }
+                           and (!$last or $last !~ /^(?:CREATE)$/i) )
+           {
                 $self->_new_line;
             }
             $self->_add_token( $token );
         }
 
-        elsif ( $token =~ /^--/ ) {
-            if ( !$self->{ 'no_comments' } ) {
+        elsif ( $token =~ /^--/ )
+       {
+            if ( !$self->{ 'no_comments' } )
+           {
                 $self->_add_token( $token );
                 $self->{ 'break' } = "\n" unless ( $self->{ 'spaces' } != 0 );
                 $self->_new_line;
                 $self->{ 'break' } = ' ' unless ( $self->{ 'spaces' } != 0 );
-            } else {
+            }
+           else
+           {
                 $self->_new_line;
             }
         }
 
-        elsif ( $token =~ /^\/\*.*\*\/$/s ) {
-            if ( !$self->{ 'no_comments' } ) {
+        elsif ( $token =~ /^\/\*.*\*\/$/s )
+       {
+            if ( !$self->{ 'no_comments' } )
+           {
                 $token =~ s/\n[\s\t]+\*/\n\*/gs;
                 $self->_new_line;
                 $self->_add_token( $token );
@@ -15878,60 +16182,81 @@ sub beautify {
             }
         }
 
-        elsif ($token =~ /^USING$/i) {
-            if (!$self->{ '_is_in_from' }) {
+        elsif ($token =~ /^USING$/i)
+       {
+            if (!$self->{ '_is_in_from' })
+           {
                 $self->_new_line;
-            } else {
+            }
+           else
+           {
                 # USING from join clause disable line break
                 $self->{ 'no_break' } = 1;
-               $self->{ '_is_in_function' }++;
+                $self->{ '_is_in_function' }++;
             }
             $self->_add_token($token);
         }
-        elsif ($token =~ /^\\\S/) { # treat everything starting with a \ and at least one character as psql meta command. 
+        elsif ($token =~ /^\\\S/)
+       {
+           # treat everything starting with a \ and at least one character as psql meta command. 
             $self->_add_token( $token );
             $self->_new_line;
         }
 
-        elsif ($token =~ /^ADD$/i && ($self->{ '_current_sql_stmt' } eq 'SEQUENCE' || $self->{ '_current_sql_stmt' } eq 'ALTER')) {
+        elsif ($token =~ /^ADD$/i && ($self->{ '_current_sql_stmt' } eq 'SEQUENCE'
+                       || $self->{ '_current_sql_stmt' } eq 'ALTER'))
+       {
             $self->_new_line;
             $self->_over;
             $self->_add_token($token);
         }
 
-        elsif ($token =~ /^INCREMENT$/i && $self->{ '_current_sql_stmt' } eq 'SEQUENCE') {
+        elsif ($token =~ /^INCREMENT$/i && $self->{ '_current_sql_stmt' } eq 'SEQUENCE')
+       {
             $self->_new_line;
             $self->_add_token($token);
         }
 
-        elsif ($token =~ /^NO$/i and $self->_next_token =~ /^(MINVALUE|MAXVALUE)$/i) {
+        elsif ($token =~ /^NO$/i and $self->_next_token =~ /^(MINVALUE|MAXVALUE)$/i)
+       {
             $self->_new_line;
             $self->_add_token($token);
         }
 
-        elsif (uc($last) ne 'NO' and $token =~ /^(MINVALUE|MAXVALUE)$/i) {
+        elsif (uc($last) ne 'NO' and $token =~ /^(MINVALUE|MAXVALUE)$/i)
+       {
             $self->_new_line;
             $self->_add_token($token);
         }
 
-        elsif ($token =~ /^CACHE$/i) {
+        elsif ($token =~ /^CACHE$/i)
+       {
             $self->_new_line;
             $self->_add_token($token);
         }
 
-        else {
-             if ($last =~ /^(?:SEQUENCE)$/i and $self->_next_token !~ /^OWNED$/i) {
+        else
+       {
+             if ($last =~ /^(?:SEQUENCE)$/i and $self->_next_token !~ /^OWNED$/i)
+            {
                  $self->_add_token( $token );
                  $self->_new_line;
                  $self->_over;
              }
-             else {
-               if (defined $last && $last eq ')' && (!defined $self->_next_token || $self->_next_token ne ';')) {
-                   if (!$self->{ '_parenthesis_level' } && $self->{ '_is_in_from' }) {
-                           $self->{ '_level' } = pop(@{ $self->{ '_level_parenthesis' } }) || 1;
-                   }
-               }
+             else
+            {
+                 if (defined $last && $last eq ')' && (!defined $self->_next_token || $self->_next_token ne ';'))
+                {
+                     if (!$self->{ '_parenthesis_level' } && $self->{ '_is_in_from' })
+                    {
+                         $self->{ '_level' } = pop(@{ $self->{ '_level_parenthesis' } }) || 1;
+                     }
+                 }
                  $self->_add_token( $token, $last );
+                 if (defined $last && uc($last) eq 'LANGUAGE' && (!defined $self->_next_token || $self->_next_token ne ';'))
+                 {
+                     $self->_new_line;
+                 }
             }
         }
 
@@ -15944,6 +16269,14 @@ sub beautify {
     return;
 }
 
+=head2 _add_token
+
+Add a token to the beautified string.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _add_token {
     my ( $self, $token, $last_token ) = @_;
 
@@ -15975,22 +16308,22 @@ sub _add_token {
             $self->{ 'content' } .= $sp if (!defined($last_token) && $token);
         } elsif ( $self->{ '_is_in_create' } == 2 && defined($last_token)) {
             $self->{ 'content' } .= $sp if ($last_token ne '::' and ($last_token ne '(' || !$self->{ '_is_in_index' }));
-       } elsif (defined $last_token) {
+    } elsif (defined $last_token) {
             $self->{ 'content' } .= $sp if ($last_token eq '(' && $self->{ '_is_in_type' });
         }
-       if ($self->_is_comment($token)) {
-               my @lines = split(/\n/, $token);
-               for (my $i = 1; $i <= $#lines; $i++) {
-                       if ($lines[$i] =~ /^\s*\*/) {
-                               $lines[$i] =~ s/^\s*\*/$sp */;
-                       } elsif ($lines[$i] =~ /^\s+[^\*]/) {
-                               $lines[$i] =~ s/^\s+/$sp /;
-                       }
-               }
-               $token = join("\n", @lines);
-       } else {
-               $token =~ s/\n/\n$sp/gs;
-       }
+    if ($self->_is_comment($token)) {
+        my @lines = split(/\n/, $token);
+        for (my $i = 1; $i <= $#lines; $i++) {
+            if ($lines[$i] =~ /^\s*\*/) {
+                $lines[$i] =~ s/^\s*\*/$sp */;
+            } elsif ($lines[$i] =~ /^\s+[^\*]/) {
+                $lines[$i] =~ s/^\s+/$sp /;
+            }
+        }
+        $token = join("\n", @lines);
+    } else {
+        $token =~ s/\n/\n$sp/gs;
+    }
     }
 
     #lowercase/uppercase keywords
@@ -16010,7 +16343,7 @@ sub _add_token {
 
     # Add formatting for HTML output
     if ( $self->{ 'colorize' } && $self->{ 'format' } eq 'html' ) {
-       $token = $self->highlight_code($token, $last_token, $self->_next_token);
+    $token = $self->highlight_code($token, $last_token, $self->_next_token);
     }
 
     $self->{ 'content' } .= $token;
@@ -16020,18 +16353,43 @@ sub _add_token {
     $self->{ '_new_line' } = 0;
 }
 
+=head2 _over
+
+Increase the indentation level.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _over {
     my ( $self ) = @_;
 
     ++$self->{ '_level' };
 }
 
+=head2 _back
+
+Decrease the indentation level.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _back {
     my ( $self ) = @_;
 
     --$self->{ '_level' } if ( $self->{ '_level' } > 0 );
 }
 
+=head2 _indent
+
+Return a string of spaces according to the current indentation level and the
+spaces setting for indenting.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _indent {
     my ( $self ) = @_;
 
@@ -16043,6 +16401,14 @@ sub _indent {
     }
 }
 
+=head2 _new_line
+
+Add a line break, but make sure there are no empty lines.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _new_line {
     my ( $self ) = @_;
 
@@ -16050,24 +16416,55 @@ sub _new_line {
     $self->{ '_new_line' } = 1;
 }
 
+=head2 _next_token
+
+Have a look at the token that's coming up next.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _next_token {
     my ( $self ) = @_;
 
     return @{ $self->{ '_tokens' } } ? $self->{ '_tokens' }->[ 0 ] : undef;
 }
 
+=head2 _token
+
+Get the next token, removing it from the list of remaining tokens.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _token {
     my ( $self ) = @_;
 
     return shift @{ $self->{ '_tokens' } };
 }
 
+=head2 _is_keyword
+
+Check if a token is a known SQL keyword.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _is_keyword {
     my ( $self, $token ) = @_;
 
     return ~~ grep { $_ eq uc( $token ) } @{ $self->{ 'keywords' } };
 }
 
+=head2 _is_comment
+
+Check if a token is a SQL or C style comment
+
+=cut
+
+
 sub _is_comment {
     my ( $self, $token ) = @_;
 
@@ -16076,6 +16473,14 @@ sub _is_comment {
     return 0;
 }
 
+=head2 _is_function
+
+Check if a token is a known SQL function.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _is_function {
     my ( $self, $token ) = @_;
 
@@ -16084,6 +16489,14 @@ sub _is_function {
     return $ret[ 0 ];
 }
 
+=head2 add_keywords
+
+Add new keywords to highlight.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub add_keywords {
     my $self = shift;
 
@@ -16092,6 +16505,14 @@ sub add_keywords {
     }
 }
 
+=head2 add_functions
+
+Add new functions to highlight.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub add_functions {
     my $self = shift;
 
@@ -16100,6 +16521,14 @@ sub add_functions {
     }
 }
 
+=head2 add_rule
+
+Add new rules.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub add_rule {
     my ( $self, $format, $token ) = @_;
 
@@ -16109,6 +16538,14 @@ sub add_rule {
     push @{ $group }, ref( $token ) ? @{ $token } : $token;
 }
 
+=head2 _get_rule
+
+Find custom rule for a token.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _get_rule {
     my ( $self, $token ) = @_;
 
@@ -16121,6 +16558,14 @@ sub _get_rule {
     return;
 }
 
+=head2 _process_rule
+
+Applies defined rule.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _process_rule {
     my ( $self, $rule, $token ) = @_;
 
@@ -16139,20 +16584,45 @@ sub _process_rule {
     }
 }
 
+=head2 _is_constant
+
+Check if a token is a constant.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _is_constant {
     my ( $self, $token ) = @_;
 
     return ( $token =~ /^\d+$/ or $token =~ /^(['"`]).*\1$/ );
 }
 
+=head2 _is_punctuation
+
+Check if a token is punctuation.
+
+Code lifted from SQL::Beautify
+
+=cut
+
 sub _is_punctuation {
     my ( $self, $token ) = @_;
     if  ($self->{ 'comma' } eq 'start' and $token eq ',') {
-       return 0;
+    return 0;
     }
     return ( $token =~ /^[,;.]$/ );
 }
 
+=head2 _generate_anonymized_string
+
+Simply generate a random string, thanks to Perlmonks.
+
+Returns original in certain cases which don't require anonymization, like
+timestamps, or intervals.
+
+=cut
+
 sub _generate_anonymized_string {
     my $self = shift;
     my ( $before, $original, $after ) = @_;
@@ -16212,6 +16682,12 @@ sub _generate_anonymized_string {
     return $cache->{ $original };
 }
 
+=head2 anonymize
+
+Anonymize litteral in SQL queries by replacing parameters with fake values
+
+=cut
+
 sub anonymize {
     my $self  = shift;
     my $query = $self->query;
@@ -16241,6 +16717,40 @@ sub anonymize {
     $self->query( $query );
 }
 
+=head2 set_defaults
+
+Sets defaults for newly created objects.
+
+Currently defined defaults:
+
+=over
+
+=item spaces => 4
+
+=item space => ' '
+
+=item break => "\n"
+
+=item uc_keywords => 0
+
+=item uc_functions => 0
+
+=item no_comments => 0
+
+=item placeholder => ''
+
+=item separator => ''
+
+=item comma => 'end'
+
+=item format => 'text'
+
+=item colorize => 1
+
+=back
+
+=cut
+
 sub set_defaults {
     my $self = shift;
     $self->set_dicts();
@@ -16266,17 +16776,34 @@ sub set_defaults {
     return;
 }
 
+=head2 format
+
+Set output format - possible values: 'text' and 'html'
+
+Default is text output. Returns 0 in case or wrong format and use default.
+
+=cut
+
 sub format {
     my $self  = shift;
     my $format  = shift;
 
     if ( grep(/^$format$/i, 'text', 'html') ) {
         $self->{ 'format' } = lc($format);
-       return 1;
+    return 1;
     }
     return 0;
 }
 
+=head2 set_dicts
+
+Sets various dictionaries (lists of keywords, functions, symbols, and the like)
+
+This was moved to separate function, so it can be put at the very end of module
+so it will be easier to read the rest of the code.
+
+=cut
+
 sub set_dicts {
     my $self = shift;
 
@@ -16666,6 +17193,13 @@ sub set_dicts {
     return;
 }
 
+=head2 _remove_dynamic_code
+
+Internal function used to hide dynamic code in plpgsql to the parser.
+The original values are restored with function _restore_dynamic_code().
+
+=cut
+
 sub _remove_dynamic_code
 {
     my ($self, $str, $code_sep) = @_;
@@ -16676,9 +17210,9 @@ sub _remove_dynamic_code
     # Try to auto detect the string separator if none are provided.
     # Note that default single quote separtor is natively supported.
     if ($#dynsep == -1) {
-       # if a dollar sign is found after EXECUTE then the following string
-       # until an other dollar is found will be understand as a text delimiter
-       @dynsep = $$str =~ /EXECUTE\s+(\$[^\$\s]*\$)/igs;
+    # if a dollar sign is found after EXECUTE then the following string
+    # until an other dollar is found will be understand as a text delimiter
+    @dynsep = $$str =~ /EXECUTE\s+(\$[^\$\s]*\$)/igs;
     }
 
     my $idx = 0;
@@ -16696,6 +17230,13 @@ sub _remove_dynamic_code
     }
 }
 
+=head2 _restore_dynamic_code
+
+Internal function used to restore plpgsql dynamic code in plpgsql
+that was removed by the _remove_dynamic_code() method.
+
+=cut
+
 sub _restore_dynamic_code
 {
         my ($self, $str) = @_;
@@ -16704,6 +17245,14 @@ sub _restore_dynamic_code
 
 }
 
+=head2 _remove_comments (OBSOLETE)
+
+Internal function used to remove comments in SQL code
+to simplify the work of the parser. Comments are restored
+with the _restore_comments() method.
+
+=cut
+
 sub _remove_comments
 {
     my ($self, $content) = @_;
@@ -16717,7 +17266,7 @@ sub _remove_comments
 
     my @lines = split(/\n/, $$content);
     for (my $j = 0; $j <= $#lines; $j++) {
-       $lines[$j] //= '';
+        $lines[$j] //= '';
         # Extract multiline comments as a single placeholder
         my $old_j = $j;
         my $cmt = '';
@@ -16762,6 +17311,13 @@ sub _remove_comments
     }
 }
 
+=head2 _restore_comments (OBSOLETE)
+
+Internal function used to restore comments in SQL code
+that was removed by the _remove_comments() method.
+
+=cut
+
 sub _restore_comments
 {
     my ($self, $content) = @_;
@@ -16769,6 +17325,30 @@ sub _restore_comments
     while ($$content =~ s/(PGF_COMMENT\d+A)[\n]*/$self->{'comments'}{$1}\n/s) { delete $self->{'comments'}{$1}; };
 }
 
+
+
+=head1 AUTHOR
+
+pgFormatter is an original work from Gilles Darold
+
+=head1 BUGS
+
+Please report any bugs or feature requests to: https://github.com/darold/pgFormatter/issues
+
+=head1 COPYRIGHT
+
+Copyright 2012-2018 Gilles Darold. All rights reserved.
+
+=head1 LICENSE
+
+pgFormatter is free software distributed under the PostgreSQL Licence.
+
+A modified version of the SQL::Beautify Perl Module is embedded in pgFormatter
+with copyright (C) 2009 by Jonas Kramer and is published under the terms of
+the Artistic License 2.0.
+
+=cut
+
 1;
 }