--- /dev/null
+package Test::SQL::Abstract::Util;
+
+use strict;
+use warnings;
+
+use Sub::Exporter -setup => {
+ exports => [qw/
+ mk_name
+ mk_value
+ mk_alias
+ field_op_value
+ /],
+ groups => [
+ dumper_sort => sub {
+
+ require Data::Dumper;
+ my $Dump = Data::Dumper->can('Dump');
+
+ no warnings 'redefine';
+
+ *Data::Dumper::Dump = sub {
+ local $Data::Dumper::Sortkeys = sub {
+ my $hash = $_[0];
+ my @keys = sort {
+ my $a_minus = substr($a,0,1) eq '-';
+ my $b_minus = substr($b,0,1) eq '-';
+
+ return $a cmp $b if $a_minus || $b_minus;
+
+ return -1 if $a eq 'op';
+ return 1 if $b eq 'op';
+ return $a cmp $b;
+ } keys %$hash;
+
+ return \@keys;
+ };
+ return $Dump->(@_);
+ };
+ return {};
+ }
+ ],
+};
+
+sub mk_alias {
+ return {
+ -type => 'alias',
+ ident => shift,
+ as => shift,
+ };
+}
+
+sub mk_name {
+ my ($field) = shift;
+ $field = ref $field eq 'HASH'
+ ? $field
+ : ref $field eq 'ARRAY'
+ ? { -type => 'identifier', elements => $field }
+ : { -type => 'identifier', elements => [$field,@_] };
+ return $field;
+}
+
+sub mk_value {
+ return { -type => 'value', value => $_[0] }
+}
+
+
+sub field_op_value {
+ my ($field, $op, $value) = @_;
+
+ $field = ref $field eq 'HASH'
+ ? $field
+ : mk_name($field);
+
+ my @value = ref $value eq 'HASH'
+ ? $value
+ : ref $value eq 'ARRAY'
+ ? @$value
+ : mk_value($value);
+
+ return {
+ -type => 'expr',
+ op => $op,
+ args => [
+ $field,
+ @value
+ ]
+ };
+}
+
+1;