beginnings of FROM, support for AS
Matt S Trout [Sun, 17 Jul 2011 00:41:01 +0000 (00:41 +0000)]
lib/Data/Query/Constants.pm
lib/Data/Query/Renderer/SQL/Naive.pm
t/expr.include
t/expr.t
t/sql.t

index 7730cde..091f587 100644 (file)
@@ -9,6 +9,9 @@ use constant +{
     DQ_OPERATOR => 'Operator',
     DQ_VALUE => 'Value',
     DQ_SELECT => 'Select',
+    DQ_ALIAS => 'Alias',
+    DQ_LITERAL => 'Literal',
+    DQ_JOIN => 'Join',
   ))
 };
 
index d8c5870..aeb98d4 100644 (file)
@@ -189,7 +189,36 @@ sub _render_select {
     \@select,
     # if present this may be a bare FROM, a FROM+WHERE, or a FROM+WHERE+GROUP
     # since we're the SELECT and therefore always come first, we don't care.
-    $dq->{from} ? @{$self->_render($dq->{from})} : ()
+    ($dq->{from}
+       ? ($self->_format_keyword('FROM'), @{$self->_render($dq->{from})})
+       : ()
+    )
+  ];
+}
+
+sub _render_alias {
+  my ($self, $dq) = @_;
+  # FROM foo foo -> FROM foo
+  # FROM foo.bar bar -> FROM foo.bar
+  if ($dq->{alias}{type} eq DQ_IDENTIFIER) {
+    if ($dq->{alias}{elements}[-1] eq $dq->{as}) {
+      return $self->_render($dq->{alias});
+    }
+  }
+  return [
+    $self->_render($dq->{alias}),
+    ' ',
+    $self->_render_identifier({ elements => [ $dq->{as} ] })
+  ];
+}
+
+sub _render_literal {
+  my ($self, $dq) = @_;
+  unless ($dq->{subtype} eq 'SQL') {
+    die "Can't render non-SQL literal";
+  }
+  return [
+    $dq->{literal},
   ];
 }
 
index fe18512..74adb47 100644 (file)
@@ -1,17 +1,19 @@
 use strictures 1;
 use Data::Query::ExprBuilder::Identifier;
-use Data::Query::Constants qw(DQ_SELECT);
+use Data::Query::Constants qw(
+  DQ_SELECT DQ_IDENTIFIER DQ_OPERATOR DQ_VALUE DQ_ALIAS
+);
 use Data::Query::ExprHelpers qw(perl_scalar_value identifier);
 
 sub expr (&) {
-  _mk_expr($_[0]);
+  _run_expr($_[0])->{expr};
 }
 
-sub _mk_expr {
+sub _run_expr {
   local $_ = Data::Query::ExprBuilder::Identifier->new({
     expr => identifier()
   });
-  $_[0]->()->{expr};
+  $_[0]->();
 }
 
 sub AS {
@@ -24,12 +26,7 @@ sub SELECT (&;@) {
     ref()
       ? $_
       : { expr => perl_scalar_value($_) }
-  ), do {
-    local $_ = Data::Query::ExprBuilder::Identifier->new({
-      expr => identifier()
-    });
-    $_[0]->();
-  };
+  ), _run_expr(shift);
   my @final;
   while (@select) {
     my $e = shift @select;
@@ -44,7 +41,26 @@ sub SELECT (&;@) {
       type => DQ_SELECT,
       select => \@final
     },
+    @_ ? (from => $_[0]->{expr}) : ()
   };
 }
 
+sub BY (&;@) { @_ }
+
+sub FROM (&;@) {
+  my @from = _run_expr(shift);
+  if (@from == 2 and ref($from[1]) eq 'LIES::AS') {
+    return +{
+      expr => {
+        type => DQ_ALIAS,
+        source => $from[0],
+        alias => identifier(${$from[1]}),
+      }
+    };
+  } elsif (@from == 1) {
+    return { expr => $from[0] };
+  }
+  die "Huh?"
+}
+
 1;
index 8b024f3..3621e11 100644 (file)
--- a/t/expr.t
+++ b/t/expr.t
@@ -6,7 +6,7 @@ BEGIN { require 't/expr.include' }
 
 sub expr_is (&;@) {
   my $sub = shift;
-  is_deeply(_mk_expr($sub), @_);
+  is_deeply(_run_expr($sub)->{expr}, @_);
 }
 
 expr_is { $_->foo }
diff --git a/t/sql.t b/t/sql.t
index f0e0d8a..1a02abc 100644 (file)
--- a/t/sql.t
+++ b/t/sql.t
@@ -14,8 +14,8 @@ sub binding { map perl_scalar_value($_), @_ }
 sub expr_sql_is (&;@) {
   my $sub = shift;
   @_
-    ? is_deeply($rend->render(_mk_expr($sub)), @_)
-    : ::Dwarn($rend->render(_mk_expr($sub)));
+    ? is_deeply($rend->render(_run_expr($sub)->{expr}), @_)
+    : ::Dwarn($rend->render(_run_expr($sub)->{expr}));
 }
 
 expr_sql_is { $_->foo }