All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SQLVisitor.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/dataaccess/query/SQLVisitor.cpp
22 
23  \brief A visitor for building an SQL statement from a given Query hierarchy.
24 */
25 
26 // TerraLib
27 #include "../../common/StringUtils.h"
28 #include "../../common/Translator.h"
29 #include "../../datatype/AbstractData.h"
30 #include "../Exception.h"
31 #include "DataSetName.h"
32 #include "Distinct.h"
33 #include "Expression.h"
34 #include "Field.h"
35 #include "Function.h"
36 #include "GroupBy.h"
37 #include "GroupByItem.h"
38 #include "Having.h"
39 #include "In.h"
40 #include "Join.h"
41 #include "JoinCondition.h"
42 #include "JoinConditionOn.h"
43 #include "JoinConditionUsing.h"
44 #include "Literal.h"
45 #include "LiteralByteArray.h"
46 #include "LiteralDateTime.h"
47 #include "LiteralDouble.h"
48 #include "LiteralGeom.h"
49 #include "LiteralInt16.h"
50 #include "LiteralInt32.h"
51 #include "LiteralInt64.h"
52 #include "LiteralString.h"
53 #include "OrderByItem.h"
54 #include "PropertyName.h"
55 #include "Select.h"
56 #include "SQLDialect.h"
57 #include "SQLFunctionEncoder.h"
58 #include "SQLVisitor.h"
59 #include "SubSelect.h"
60 #include "Where.h"
61 
62 // STL
63 #include <cassert>
64 
65 void te::da::SQLVisitor::visit(const Expression& /*visited*/)
66 {
67 }
68 
70 {
71  m_sql += visited.getName();
72 
73  if(visited.getAlias().empty() == false)
74  {
75  m_sql += " AS ";
76  m_sql += visited.getAlias();
77  }
78 }
79 
80 void te::da::SQLVisitor::visit(const FromItem& /*visited*/)
81 {
82 }
83 
84 void te::da::SQLVisitor::visit(const Function& visited)
85 {
86  const std::string& fname = visited.getName();
87 
88  const SQLFunctionEncoder* encoder = m_dialect.find(fname);
89 
90  if(encoder == 0)
91  throw Exception(TR_DATAACCESS("The informed function is not supported by this driver!"));
92 
93  encoder->toSQL(visited, m_sql, *this);
94 }
95 
96 void te::da::SQLVisitor::visit(const Join& visited)
97 {
98  assert(visited.getFirst() && visited.getSecond());
99 
100  m_sql += "(";
101  visited.getFirst()->accept(*this);
102 
103  if(visited.isNatural())
104  m_sql += " NATURAL ";
105 
106  switch(visited.getType())
107  {
108  case JOIN :
109  m_sql += " JOIN ";
110  break;
111 
112  case INNER_JOIN :
113  m_sql += " INNER JOIN ";
114  break;
115 
116  case LEFT_JOIN :
117  m_sql += " LEFT JOIN ";
118  break;
119 
120  case RIGHT_JOIN :
121  m_sql += " RIGHT JOIN ";
122  break;
123 
124  case FULL_OUTER_JOIN :
125  m_sql += " FULL OUTER JOIN ";
126  break;
127 
128  case CROSS_JOIN :
129  m_sql += " CROSS JOIN ";
130  break;
131 
132  case NATURAL_JOIN :
133  m_sql += " NATURAL JOIN ";
134  break;
135  }
136 
137  visited.getSecond()->accept(*this);
138 
139  if(visited.getCondition())
140  {
141  m_sql += " ";
142  visited.getCondition()->accept(*this);
143  }
144 
145  m_sql += ")";
146 }
147 
148 void te::da::SQLVisitor::visit(const JoinCondition& /*visited*/)
149 {
150 }
151 
153 {
154  assert(visited.getCondition());
155  m_sql += "ON (";
156  visited.getCondition()->accept(*this);
157  m_sql += ")";
158 }
159 
161 {
162  m_sql += "USING (";
163 
164  size_t ncols = visited.getNumFields();
165 
166  for(size_t i = 0; i < ncols; ++i)
167  {
168  if(i != 0)
169  m_sql += ", ";
170 
171  assert(visited[i]);
172  visited[i]->accept(*this);
173  }
174 
175  m_sql += ")";
176 }
177 
178 void te::da::SQLVisitor::visit(const Literal& visited)
179 {
180  if(visited.getValue())
181  m_sql += visited.getValue()->toString();
182 }
183 
185 {
186  if(visited.getValue())
187  m_sql += visited.getValue()->toString();
188 }
189 
191 {
192  if(visited.getValue())
193  m_sql += visited.getValue()->toString();
194 }
195 
197 {
198  if(visited.getValue())
199  m_sql += visited.getValue()->toString();
200 }
201 
203 {
204 }
205 
207 {
208  if(visited.getValue())
209  m_sql += visited.getValue()->toString();
210 }
211 
213 {
214  if(visited.getValue())
215  m_sql += visited.getValue()->toString();
216 }
217 
219 {
220  if(visited.getValue())
221  m_sql += visited.getValue()->toString();
222 }
223 
225 {
226  if(visited.getValue())
227  m_sql += visited.getValue()->toString();
228 }
229 
231 {
232  if(visited.getValue())
233  {
234  m_sql += "'";
235  m_sql += visited.getValue()->toString();
236  m_sql += "'";
237  }
238 }
239 
241 {
242  m_sql += visited.getName();
243 }
244 
245 void te::da::SQLVisitor::visit(const Query& /*visited*/)
246 {
247 }
248 
249 void te::da::SQLVisitor::visit(const Select& visited)
250 {
251  m_sql += "SELECT ";
252 
253  if(visited.getDistinct())
254  {
255  visitDistinct(*(visited.getDistinct()));
256  m_sql += " ";
257  }
258 
259  if(visited.getFields())
260  {
261  visit(*(visited.getFields()));
262  m_sql += " ";
263  }
264 
265  if(visited.getFrom())
266  {
267  visit(*(visited.getFrom()));
268  m_sql += " ";
269  }
270 
271  if(visited.getWhere())
272  {
273  m_sql += "WHERE ";
274  visited.getWhere()->getExp()->accept(*this);
275  m_sql += " ";
276  }
277 
278  if(visited.getGroupBy())
279  {
280  visit(*(visited.getGroupBy()));
281  m_sql += " ";
282  }
283 
284  if(visited.getHaving())
285  {
286  m_sql += "HAVING ";
287  visited.getHaving()->getExp()->accept(*this);
288  m_sql += " ";
289  }
290 
291  if(visited.getOrderBy())
292  visit(*(visited.getOrderBy()));
293 }
294 
296 {
297  assert(visited.getSelect());
298  visited.getSelect()->accept(*this);
299 
300  if(visited.getAlias().empty() == false)
301  {
302  m_sql += " AS ";
303  m_sql += visited.getAlias();
304  }
305 }
306 
307 void te::da::SQLVisitor::visit(const In& visited)
308 {
309  assert(visited.getPropertyName());
310  visited.getPropertyName()->accept(*this);
311 
312  m_sql += " IN";
313  m_sql += "(";
314 
315  for(size_t i = 0; i < visited.getNumArgs(); ++i)
316  {
317  if(i != 0)
318  m_sql += ", ";
319 
320  assert(visited[i]);
321  visited[i]->accept(*this);
322  }
323 
324  m_sql += ")";
325 }
326 
328 {
329  if(visited.empty())
330  {
331  m_sql += "DISTINCT";
332  }
333  else
334  {
335  m_sql += "DISTINCT ON(";
336 
337  std::size_t ncols = visited.size();
338 
339  for(std::size_t i = 0; i < ncols; ++i)
340  {
341  if(i != 0)
342  m_sql += ", ";
343 
344  visited[i].accept(*this);
345  }
346 
347  m_sql += ")";
348  }
349 }
350 
352 {
353  std::size_t size = visited.size();
354 
355  for(size_t i = 0; i < size; ++i)
356  {
357  if(i != 0)
358  m_sql += ", ";
359 
360  visited[i].getExpression()->accept(*this);
361 
362  if(visited[i].getAlias())
363  m_sql += *(visited[i].getAlias());
364  }
365 }
366 
368 {
369  std::size_t size = visited.size();
370 
371  m_sql += "FROM ";
372 
373  for(std::size_t i = 0; i < size; ++i)
374  {
375  if(i != 0)
376  m_sql += ", ";
377 
378  visited[i].accept(*this);
379  }
380 }
381 
383 {
384  m_sql += "GROUP BY ";
385 
386  std::size_t ncols = visited.size();
387 
388  for(std::size_t i = 0; i < ncols; ++i)
389  {
390  if(i != 0)
391  m_sql += ", ";
392 
393  visited[i].getExpression()->accept(*this);
394  }
395 }
396 
398 {
399  std::size_t size = visited.size();
400 
401  m_sql += "ORDER BY ";
402 
403  for(std::size_t i = 0; i < size; ++i)
404  {
405  if(i != 0)
406  m_sql += ", ";
407 
408  visited[i].getExpression()->accept(*this);
409 
410  if(visited[i].getSortOrder() == te::da::ASC)
411  m_sql += " ASC";
412  else
413  m_sql += " DESC";
414  }
415 }
A class that models a Literal for a integer value.
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
JoinConditionUsing class can be used to model a USING clause in a Join.
const Having * getHaving() const
It returns the list of expressions used to eliminate group row that doesn&#39;t satisfy the condition...
Definition: Select.cpp:972
JoinConditionOn is a boolean expression and it specifies which items in a join are considered to matc...
A class that models a literal for Date and Time values.
A condition to be used in a Join clause.
A Select models a query to be used when retrieving data from a data source.
virtual void toSQL(const Function &f, std::string &buff, SQLVisitor &v) const =0
It encodes the function to a SQL notation.
PropertyName * getPropertyName() const
It returns the property name.
Definition: In.cpp:82
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
A class that can be used in an ORDER BY clause to sort the items of a resulting query.
A base class for encoders of SQL function expressions.
A class that models a Distinct clause on a query.
A visitor for building an SQL statement from a given Query hierarchy.
const std::string & getName() const
It returns the property name.
Definition: PropertyName.h:80
FromItem * getSecond() const
It returns the second item involved in the join.
Definition: Join.cpp:101
virtual std::string toString() const =0
It returns the data value in a string notation.
A class that models a literal for double values.
This class models a string Literal value.
Definition: LiteralString.h:46
const std::string & getName() const
It returns the dataset name.
Definition: DataSetName.cpp:57
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
A class that models the name of any property of an object.
A base class for encoders of SQL function expressions.
A class that models the name of any property of an object.
Definition: PropertyName.h:50
const From * getFrom() const
It returns the list of source information to be used by the query.
Definition: Select.cpp:942
It represents the SQL query dialect accepted by a given data source.
A class that models a Literal String value.
A class that models a Literal for a integer value.
JoinConditionOn is a boolean expression and it specifies which items in a join are considered to matc...
A class that can be used to model a GROUP BY clause.
A Select can be used as a source of information in another query.
A class that models a literal for Geometry values.
Definition: LiteralGeom.h:46
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
std::size_t getNumArgs() const
It returns the number of arguments informed to the function.
Definition: Function.cpp:62
const Distinct * getDistinct() const
It returns the Distinct modifier.
Definition: Select.cpp:992
An abstract class that models a source of data in a query.
Definition: FromItem.h:50
JoinCondition * getCondition() const
It returns the join condition.
Definition: Join.cpp:121
This class models a literal value.
virtual void visit(const Expression &visited)
Definition: SQLVisitor.cpp:65
A Query is independent from the data source language/dialect.
Definition: Query.h:46
A class that models a literal for ByteArray values.
const std::string & getAlias() const
It returns the alias associated to the source item.
Definition: FromItem.cpp:47
virtual void visitDistinct(const Distinct &visited)
Definition: SQLVisitor.cpp:327
A class that can be used to model a filter expression that can be applied to a query.
A class that models a Literal for a integer value.
Expression * getCondition() const
It returns a pointer to a join condition.
A class that models a literal for ByteArray values.
JoinConditionUsing class can be used to model a USING clause in a Join.
A class that models a literal for Envelope values.
A Having is a filter expression that can be applied to a query with a group by clause.
A class that models a Function expression.
Expression * getExp() const
Definition: Having.cpp:60
A class that models the name of a dataset used in a From clause.
boost::ptr_vector< OrderByItem > OrderBy
A class that can be used to model an ORDER BY clause.
Definition: OrderBy.h:37
A class that can be used in a GROUP BY clause.
The Field class can be used to model an expression that takes part of the output items of a SELECT...
boost::ptr_vector< Expression > Distinct
A class that models a Distinct clause on a query.
Definition: Distinct.h:37
FromItem * getFirst() const
It returns the first from item involved in the join.
Definition: Join.cpp:91
JoinType getType() const
It returns the join type.
Definition: Join.cpp:111
A class that models a literal for Geometry values.
#define TR_DATAACCESS(message)
It marks a string in order to get translated. This is a special mark used in the DataAccess module of...
Definition: Config.h:95
A condition to be used in a Join clause.
Definition: JoinCondition.h:44
Select * getSelect() const
It returns the associated subselect.
Definition: SubSelect.cpp:69
boost::ptr_vector< GroupByItem > GroupBy
A class that can be used to model a GROUP BY clause.
Definition: GroupBy.h:37
This class models a literal value.
Definition: Literal.h:53
const GroupBy * getGroupBy() const
It returns the list of expressions used to condense the result set.
Definition: Select.cpp:962
const std::string & getName() const
It returns the function name.
Definition: Function.h:79
Expression * getExp() const
Definition: Where.cpp:60
This is an abstract class that models a query expression.
This is an abstract class that models a query expression.
Definition: Expression.h:47
const Fields * getFields() const
It returns the list of output expressions used to form the result set.
Definition: Select.cpp:932
virtual ReturnType accept(VisitorType &guest) const =0
It call the visit method from the guest object.
const OrderBy * getOrderBy() const
It returns the list of expressions used to sort the output result.
Definition: Select.cpp:982
A Select can be used as a source of information in another query.
Definition: SubSelect.h:49
Where * getWhere() const
It returns the filter condition.
Definition: Select.cpp:952
bool isNatural() const
It tells if the join is Natural.
Definition: Join.h:141
A Join clause combines two FromItems.
A class that models a Function expression.
Definition: Function.h:47
A Join clause combines two FromItems.
Definition: Join.h:50
A class that models a literal for double values.
Definition: LiteralDouble.h:43
std::size_t getNumFields() const
It returns the number of fields in this join condition.
A class that models a literal for Date and Time values.
te::dt::AbstractData * getValue() const
It returns the value associated to the literal.
Definition: Literal.cpp:65
A class that represents the IN operator.
Definition: In.h:52
A class that represents the IN operator.