From a07c0c0a6a1fc0eebcbc4e857b6ce57c8d7c8cc8 Mon Sep 17 00:00:00 2001 From: Daniel Nichter Date: Mon, 18 Feb 2013 12:31:18 -0700 Subject: [PATCH] Updqte Quoter in all tools. --- bin/pt-archiver | 88 +++++++++++++++++++++-------------- bin/pt-deadlock-logger | 88 +++++++++++++++++++++-------------- bin/pt-duplicate-key-checker | 88 +++++++++++++++++++++-------------- bin/pt-find | 88 +++++++++++++++++++++-------------- bin/pt-fk-error-logger | 88 +++++++++++++++++++++-------------- bin/pt-heartbeat | 88 +++++++++++++++++++++-------------- bin/pt-index-usage | 88 +++++++++++++++++++++-------------- bin/pt-kill | 88 +++++++++++++++++++++-------------- bin/pt-online-schema-change | 88 +++++++++++++++++++++-------------- bin/pt-query-advisor | 88 +++++++++++++++++++++-------------- bin/pt-query-digest | 88 +++++++++++++++++++++-------------- bin/pt-slave-restart | 88 +++++++++++++++++++++-------------- bin/pt-table-checksum | 88 +++++++++++++++++++++-------------- bin/pt-table-sync | 88 +++++++++++++++++++++-------------- bin/pt-table-usage | 89 ++++++++++++++++++++++++------------ bin/pt-upgrade | 88 +++++++++++++++++++++-------------- 16 files changed, 855 insertions(+), 554 deletions(-) diff --git a/bin/pt-archiver b/bin/pt-archiver index e91c9760..b53ce152 100755 --- a/bin/pt-archiver +++ b/bin/pt-archiver @@ -2521,6 +2521,11 @@ use warnings FATAL => 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -2585,51 +2590,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -1793,51 +1798,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -127,51 +132,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -1525,51 +1530,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -1148,51 +1153,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -2463,51 +2468,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -510,51 +515,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -4186,51 +4191,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -2741,51 +2746,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -1536,51 +1541,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -529,51 +534,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -125,51 +130,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -3523,51 +3528,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -1616,51 +1621,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -5539,12 +5544,18 @@ sub quote_val { sub split_unquote { my ( $self, $db_tbl, $default_db ) = @_; - $db_tbl =~ s/`//g; my ( $db, $tbl ) = split(/[.]/, $db_tbl); if ( !$tbl ) { $tbl = $db; $db = $default_db; } + for ($db, $tbl) { + next unless $_; + s/\A`//; + s/`\z//; + s/``/`/g; + } + return ($db, $tbl); } @@ -5570,44 +5581,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - die "Cannot serialize multiple values with undef/NULL" - if grep { !defined $_ } @args; - - return join ',', map { quotemeta } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; + my @parts; + foreach my $arg ( split(/(? 'all'; use English qw(-no_match_vars); use constant PTDEBUG => $ENV{PTDEBUG} || 0; +use Data::Dumper; +$Data::Dumper::Indent = 1; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Quotekeys = 0; + sub new { my ( $class, %args ) = @_; return bless {}, $class; @@ -934,51 +939,64 @@ sub join_quote { sub serialize_list { my ( $self, @args ) = @_; - return unless @args; + PTDEBUG && _d('Serializing', Dumper(\@args)); + die "Cannot serialize an empty array" unless scalar @args; - return $args[0] if @args == 1 && !defined $args[0]; + my @parts; + foreach my $arg ( @args ) { + if ( defined $arg ) { + $arg =~ s/,/\\,/g; # escape commas + $arg =~ s/\\N/\\\\N/g; # escape literal \N + push @parts, $arg; + } + else { + push @parts, '\N'; + } + } - return join ',', map { - my $c = $_; - if ( defined($c) ) { - $c =~ s/([^A-Za-z0-9])/\\$1/g; - $c - } - else { - '\\N' - } - } @args; + my $string = join(',', @parts); + PTDEBUG && _d('Serialized: <', $string, '>'); + return $string; } sub deserialize_list { my ( $self, $string ) = @_; - return $string unless defined $string; - my @escaped_parts = $string =~ / - \G # Start of string, or end of previous match. - ( # Each of these is an element in the original list. - [^\\,]* # Anything not a backslash or a comma - (?: # When we get here, we found one of the above. - \\. # A backslash followed by something so we can continue - [^\\,]* # Same as above. - )* # Repeat zero of more times. - ) - , # Comma dividing elements - /sxgc; + PTDEBUG && _d('Deserializing <', $string, '>'); + die "Cannot deserialize an undefined string" unless defined $string; - push @escaped_parts, pos($string) ? substr( $string, pos($string) ) : $string; - - my @unescaped_parts = map { - my $part = $_; - if ($part eq '\\N') { - undef + my @parts; + foreach my $arg ( split(/(?