OmniSciDB  c07336695a
OmniSciStatement.java
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.omnisci.jdbc;
17 
18 import com.mapd.thrift.server.MapD;
19 import com.mapd.thrift.server.TMapDException;
20 import com.mapd.thrift.server.TQueryResult;
21 
22 import org.apache.thrift.TException;
23 import org.slf4j.LoggerFactory;
24 
25 import java.sql.Connection;
26 import java.sql.ResultSet;
27 import java.sql.SQLException;
28 import java.sql.SQLWarning;
29 import java.util.regex.Pattern;
30 
35 public class OmniSciStatement implements java.sql.Statement {
36  final static org.slf4j.Logger logger = LoggerFactory.getLogger(OmniSciStatement.class);
37  public SQLWarning rootWarning = null;
38 
39  private String session;
40  private MapD.Client client;
41  private ResultSet currentRS = null;
42  private TQueryResult sqlResult = null;
43  private int maxRows = 100000; // add limit to unlimited queries
44  private boolean escapeProcessing = false;
45 
46  OmniSciStatement(String tsession, MapD.Client tclient) {
47  session = tsession;
48  client = tclient;
49  }
50 
51  @Override
52  public ResultSet executeQuery(String sql)
53  throws SQLException { // logger.debug("Entered");
54  if (maxRows > 0) {
55  // add limit to sql call if it doesn't already have one and is a select
56  String[] tokens = sql.toLowerCase().split(" ", 3);
57  if (tokens[0].equals("select")) {
58  if (sql.toLowerCase().contains("limit")) {
59  // do nothing
60  } else {
61  sql = sql + " LIMIT " + maxRows;
62  logger.debug("Added LIMIT of " + maxRows);
63  }
64  }
65  }
66  logger.debug("sql is :'" + sql + "'");
67  String afterFnSQL = fnReplace(sql);
68  logger.debug("afterFnSQL is :'" + afterFnSQL + "'");
69  try {
70  sqlResult = client.sql_execute(session, afterFnSQL + ";", true, null, -1, -1);
71  } catch (TMapDException ex) {
72  throw new SQLException("Query failed : " + ex.getError_msg());
73  } catch (TException ex) {
74  throw new SQLException("Query failed : " + ex.toString());
75  }
76 
77  currentRS = new OmniSciResultSet(sqlResult, sql);
78  return currentRS;
79  }
80 
81  @Override
82  public int executeUpdate(String sql) throws SQLException { // logger.debug("Entered");
83  try {
84  // remove " characters if it is a CREATE statement
85  if (sql.trim().substring(0, 6).compareToIgnoreCase("CREATE") == 0) {
86  sql = sql.replace('"', ' ');
87  }
88  sqlResult = client.sql_execute(session, sql + ";", true, null, -1, -1);
89  } catch (TMapDException ex) {
90  throw new SQLException(
91  "Query failed : " + ex.getError_msg() + " sql was '" + sql + "'");
92  } catch (TException ex) {
93  throw new SQLException("Query failed : " + ex.toString());
94  }
95 
96  return sqlResult.row_set.columns.size();
97  }
98 
99  @Override
100  public void close() throws SQLException { // logger.debug("Entered");
101 
102  // clean up after -- nothing to do
103  }
104 
105  @Override
106  public int getMaxFieldSize() throws SQLException { // logger.debug("Entered");
107  throw new UnsupportedOperationException("Not supported yet,"
108  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
109  + " class:" + new Throwable().getStackTrace()[0].getClassName()
110  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
111  }
112 
113  @Override
114  public void setMaxFieldSize(int max) throws SQLException { // logger.debug("Entered");
115  throw new UnsupportedOperationException("Not supported yet,"
116  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
117  + " class:" + new Throwable().getStackTrace()[0].getClassName()
118  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
119  }
120 
121  @Override
122  public int getMaxRows() throws SQLException { // logger.debug("Entered");
123  return maxRows;
124  }
125 
126  @Override
127  public void setMaxRows(int max) throws SQLException { // logger.debug("Entered");
128  maxRows = max;
129  }
130 
131  @Override
132  public void setEscapeProcessing(boolean enable)
133  throws SQLException { // logger.debug("Entered");
134  escapeProcessing = enable;
135  }
136 
137  @Override
138  public int getQueryTimeout() throws SQLException { // logger.debug("Entered");
139  return 0;
140  }
141 
142  // used by benchmarking to get internal execution times
144  throws SQLException { // logger.debug("Entered");
145  return (int) sqlResult.execution_time_ms;
146  }
147 
148  @Override
149  public void setQueryTimeout(int seconds)
150  throws SQLException { // logger.debug("Entered");
151  SQLWarning warning = new SQLWarning(
152  "Query timeouts are not supported. Substituting a value of zero.");
153  if (rootWarning == null) {
154  rootWarning = warning;
155  } else {
156  rootWarning.setNextWarning(warning);
157  }
158  }
159 
160  @Override
161  public void cancel() throws SQLException { // logger.debug("Entered");
162  throw new UnsupportedOperationException("Not supported yet,"
163  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
164  + " class:" + new Throwable().getStackTrace()[0].getClassName()
165  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
166  }
167 
168  @Override
169  public SQLWarning getWarnings() throws SQLException { // logger.debug("Entered");
170  return (rootWarning);
171  }
172 
173  @Override
174  public void clearWarnings() throws SQLException { // logger.debug("Entered");
175  rootWarning = null;
176  }
177 
178  @Override
179  public void setCursorName(String name) throws SQLException { // logger.debug("Entered");
180  throw new UnsupportedOperationException("Not supported yet,"
181  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
182  + " class:" + new Throwable().getStackTrace()[0].getClassName()
183  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
184  }
185 
186  @Override
187  public boolean execute(String sql) throws SQLException { // logger.debug("Entered");
188  ResultSet rs = executeQuery(sql);
189  if (rs != null) {
190  return true;
191  } else {
192  return false;
193  }
194  }
195 
196  @Override
197  public ResultSet getResultSet() throws SQLException { // logger.debug("Entered");
198  return currentRS;
199  }
200 
201  @Override
202  public int getUpdateCount() throws SQLException { // logger.debug("Entered");
203  // TODO MAT fix update count
204  return 0;
205  }
206 
207  @Override
208  public boolean getMoreResults() throws SQLException { // logger.debug("Entered");
209  // TODO MAT this needs to be fixed for complex queries
210  return false;
211  }
212 
213  @Override
214  public void setFetchDirection(int direction)
215  throws SQLException { // logger.debug("Entered");
216  throw new UnsupportedOperationException("Not supported yet,"
217  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
218  + " class:" + new Throwable().getStackTrace()[0].getClassName()
219  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
220  }
221 
222  @Override
223  public int getFetchDirection() throws SQLException { // logger.debug("Entered");
224  throw new UnsupportedOperationException("Not supported yet,"
225  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
226  + " class:" + new Throwable().getStackTrace()[0].getClassName()
227  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
228  }
229 
230  @Override
231  public void setFetchSize(int rows) throws SQLException { // logger.debug("Entered");
232  SQLWarning warning = new SQLWarning(
233  "Query FetchSize are not supported. Substituting a value of zero.");
234  if (rootWarning == null) {
235  rootWarning = warning;
236  } else {
237  rootWarning.setNextWarning(warning);
238  }
239  }
240 
241  @Override
242  public int getFetchSize() throws SQLException { // logger.debug("Entered");
243  throw new UnsupportedOperationException("Not supported yet,"
244  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
245  + " class:" + new Throwable().getStackTrace()[0].getClassName()
246  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
247  }
248 
249  @Override
250  public int getResultSetConcurrency() throws SQLException { // logger.debug("Entered");
251  throw new UnsupportedOperationException("Not supported yet,"
252  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
253  + " class:" + new Throwable().getStackTrace()[0].getClassName()
254  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
255  }
256 
257  @Override
258  public int getResultSetType() throws SQLException { // logger.debug("Entered");
259  throw new UnsupportedOperationException("Not supported yet,"
260  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
261  + " class:" + new Throwable().getStackTrace()[0].getClassName()
262  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
263  }
264 
265  @Override
266  public void addBatch(String sql) throws SQLException { // logger.debug("Entered");
267  throw new UnsupportedOperationException("Not supported yet,"
268  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
269  + " class:" + new Throwable().getStackTrace()[0].getClassName()
270  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
271  }
272 
273  @Override
274  public void clearBatch() throws SQLException { // logger.debug("Entered");
275  throw new UnsupportedOperationException("Not supported yet,"
276  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
277  + " class:" + new Throwable().getStackTrace()[0].getClassName()
278  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
279  }
280 
281  @Override
282  public int[] executeBatch() throws SQLException { // logger.debug("Entered");
283  throw new UnsupportedOperationException("Not supported yet,"
284  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
285  + " class:" + new Throwable().getStackTrace()[0].getClassName()
286  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
287  }
288 
289  @Override
290  public Connection getConnection() throws SQLException { // logger.debug("Entered");
291  throw new UnsupportedOperationException("Not supported yet,"
292  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
293  + " class:" + new Throwable().getStackTrace()[0].getClassName()
294  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
295  }
296 
297  @Override
298  public boolean getMoreResults(int current)
299  throws SQLException { // logger.debug("Entered");
300  throw new UnsupportedOperationException("Not supported yet,"
301  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
302  + " class:" + new Throwable().getStackTrace()[0].getClassName()
303  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
304  }
305 
306  @Override
307  public ResultSet getGeneratedKeys() throws SQLException { // logger.debug("Entered");
308  throw new UnsupportedOperationException("Not supported yet,"
309  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
310  + " class:" + new Throwable().getStackTrace()[0].getClassName()
311  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
312  }
313 
314  @Override
315  public int executeUpdate(String sql, int autoGeneratedKeys)
316  throws SQLException { // logger.debug("Entered");
317  throw new UnsupportedOperationException("Not supported yet,"
318  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
319  + " class:" + new Throwable().getStackTrace()[0].getClassName()
320  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
321  }
322 
323  @Override
324  public int executeUpdate(String sql, int[] columnIndexes)
325  throws SQLException { // logger.debug("Entered");
326  throw new UnsupportedOperationException("Not supported yet,"
327  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
328  + " class:" + new Throwable().getStackTrace()[0].getClassName()
329  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
330  }
331 
332  @Override
333  public int executeUpdate(String sql, String[] columnNames)
334  throws SQLException { // logger.debug("Entered");
335  throw new UnsupportedOperationException("Not supported yet,"
336  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
337  + " class:" + new Throwable().getStackTrace()[0].getClassName()
338  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
339  }
340 
341  @Override
342  public boolean execute(String sql, int autoGeneratedKeys)
343  throws SQLException { // logger.debug("Entered");
344  throw new UnsupportedOperationException("Not supported yet,"
345  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
346  + " class:" + new Throwable().getStackTrace()[0].getClassName()
347  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
348  }
349 
350  @Override
351  public boolean execute(String sql, int[] columnIndexes)
352  throws SQLException { // logger.debug("Entered");
353  throw new UnsupportedOperationException("Not supported yet,"
354  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
355  + " class:" + new Throwable().getStackTrace()[0].getClassName()
356  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
357  }
358 
359  @Override
360  public boolean execute(String sql, String[] columnNames)
361  throws SQLException { // logger.debug("Entered");
362  throw new UnsupportedOperationException("Not supported yet,"
363  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
364  + " class:" + new Throwable().getStackTrace()[0].getClassName()
365  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
366  }
367 
368  @Override
369  public int getResultSetHoldability() throws SQLException { // logger.debug("Entered");
370  throw new UnsupportedOperationException("Not supported yet,"
371  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
372  + " class:" + new Throwable().getStackTrace()[0].getClassName()
373  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
374  }
375 
376  @Override
377  public boolean isClosed() throws SQLException { // logger.debug("Entered");
378  throw new UnsupportedOperationException("Not supported yet,"
379  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
380  + " class:" + new Throwable().getStackTrace()[0].getClassName()
381  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
382  }
383 
384  @Override
385  public void setPoolable(boolean poolable)
386  throws SQLException { // logger.debug("Entered");
387  throw new UnsupportedOperationException("Not supported yet,"
388  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
389  + " class:" + new Throwable().getStackTrace()[0].getClassName()
390  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
391  }
392 
393  @Override
394  public boolean isPoolable() throws SQLException { // logger.debug("Entered");
395  throw new UnsupportedOperationException("Not supported yet,"
396  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
397  + " class:" + new Throwable().getStackTrace()[0].getClassName()
398  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
399  }
400 
401  @Override
402  public void closeOnCompletion() throws SQLException { // logger.debug("Entered");
403  throw new UnsupportedOperationException("Not supported yet,"
404  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
405  + " class:" + new Throwable().getStackTrace()[0].getClassName()
406  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
407  }
408 
409  @Override
410  public boolean isCloseOnCompletion() throws SQLException { // logger.debug("Entered");
411  throw new UnsupportedOperationException("Not supported yet,"
412  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
413  + " class:" + new Throwable().getStackTrace()[0].getClassName()
414  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
415  }
416 
417  @Override
418  public <T> T unwrap(Class<T> iface) throws SQLException { // logger.debug("Entered");
419  throw new UnsupportedOperationException("Not supported yet,"
420  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
421  + " class:" + new Throwable().getStackTrace()[0].getClassName()
422  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
423  }
424 
425  @Override
426  public boolean isWrapperFor(Class<?> iface)
427  throws SQLException { // logger.debug("Entered");
428  throw new UnsupportedOperationException("Not supported yet,"
429  + " line:" + new Throwable().getStackTrace()[0].getLineNumber()
430  + " class:" + new Throwable().getStackTrace()[0].getClassName()
431  + " method:" + new Throwable().getStackTrace()[0].getMethodName());
432  }
433 
434  private static final Pattern QUARTER = Pattern.compile(
435  "\\sQUARTER\\(([^\\{]*?)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
436  private static final Pattern DAYOFYEAR = Pattern.compile(
437  "\\sDAYOFYEAR\\(([^\\{]*?)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
438  private static final Pattern DAYOFWEEK = Pattern.compile(
439  "\\sDAYOFWEEK\\(([^\\{]*?)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
440  private static final Pattern WEEK = Pattern.compile(
441  "\\sWEEK\\(([^\\{]*?)", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
442  private static final Pattern QUARTER_TRUNC = Pattern.compile(
443  "\\(\\(\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ FLOOR\\(\\(\\-1 \\* \\( EXTRACT\\(DAY FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' DAY\\) \\+ FLOOR\\(\\(\\-1 \\* \\( EXTRACT\\(MONTH FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' MONTH\\) \\+ FLOOR\\(\\(3 \\* \\( FLOOR\\( EXTRACT\\(QUARTER FROM .*?\\)\\) - 1\\)\\)\\) \\* INTERVAL '1' MONTH\\)",
444  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
445  private static final Pattern MONTH_TRUNC = Pattern.compile(
446  "\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ FLOOR\\(\\(\\-1 \\* \\( EXTRACT\\(DAY FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' DAY\\)",
447  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
448  private static final Pattern YEAR_TRUNC = Pattern.compile(
449  "\\(\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ FLOOR\\(\\(\\-1 \\* \\( EXTRACT\\(DAY FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' DAY\\) \\+ FLOOR\\(\\(\\-1\\ \\* \\( EXTRACT\\(MONTH FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' MONTH\\)",
450  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
451 
452  private static final Pattern MINUTE_TRUNC = Pattern.compile(
453  "\\(\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ EXTRACT\\(HOUR FROM .*?\\) \\* INTERVAL '1' HOUR\\) \\+ EXTRACT\\(MINUTE FROM .*?\\) \\* INTERVAL '1' MINUTE\\)",
454  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
455  private static final Pattern SECOND_TRUNC = Pattern.compile(
456  "\\(\\(\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ EXTRACT\\(HOUR FROM .*?\\) \\* INTERVAL '1' HOUR\\) \\+ EXTRACT\\(MINUTE FROM .*?\\) \\* INTERVAL '1' MINUTE\\) \\+ EXTRACT\\(SECOND FROM .*?\\) \\* INTERVAL '1' SECOND\\)",
457  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
458 
459  private static final Pattern YEAR1_TRUNC = Pattern.compile(
460  "\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ FLOOR\\(\\(\\-1 \\* \\( EXTRACT\\(DOY FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' DAY\\)",
461  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
462 
463  private static final Pattern QUARTER1_TRUNC = Pattern.compile(
464  "\\(\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ FLOOR\\(\\(\\-1 \\* \\( EXTRACT\\(DOY FROM .*?\\) \\- 1\\)\\)\\) \\* INTERVAL '1' DAY\\) \\+ FLOOR\\(\\(3 \\* \\( FLOOR\\( EXTRACT\\(QUARTER FROM .*?\\)\\) \\- 1\\)\\)\\) \\* INTERVAL '1' MONTH\\)",
465  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
466 
467  private static final Pattern WEEK_TRUNC = Pattern.compile(
468  "\\(CAST\\(([^\\(]*?) AS DATE\\) \\+ \\(\\-1 \\* \\( EXTRACT\\(ISODOW FROM .*?\\) \\- 1\\)\\) \\* INTERVAL '1' DAY\\)",
469  Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
470 
471  public static String fnReplace(String sql) {
472  // need to iterate as each reduction of string opens up a anew match
473  String start;
474  do {
475  start = sql;
476  sql = QUARTER.matcher(sql).replaceAll(" EXTRACT(QUARTER FROM $1");
477  } while (!sql.equals(start));
478 
479  do {
480  start = sql;
481  sql = DAYOFYEAR.matcher(sql).replaceAll(" EXTRACT(DOY FROM $1");
482  } while (!sql.equals(start));
483 
484  do {
485  start = sql;
486  sql = DAYOFWEEK.matcher(sql).replaceAll(" EXTRACT(ISODOW FROM $1");
487  } while (!sql.equals(start));
488 
489  do {
490  start = sql;
491  sql = WEEK.matcher(sql).replaceAll(" EXTRACT(WEEK FROM $1");
492  } while (!sql.equals(start));
493 
494  // Order is important here, do not shuffle without checking
495  sql = QUARTER_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(QUARTER, $1)");
496  sql = YEAR_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(YEAR, $1)");
497  sql = SECOND_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(SECOND, $1)");
498  sql = QUARTER1_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(QUARTER, $1)");
499  sql = MONTH_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(MONTH, $1)");
500  sql = MINUTE_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(MINUTE, $1)");
501  sql = YEAR1_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(YEAR, $1)");
502  sql = WEEK_TRUNC.matcher(sql).replaceAll(" DATE_TRUNC(WEEK, $1)");
503 
504  do {
505  start = sql;
506  sql = QUARTER.matcher(sql).replaceAll(" EXTRACT(QUARTER FROM $1");
507  } while (!sql.equals(start));
508 
509  do {
510  start = sql;
511  sql = DAYOFYEAR.matcher(sql).replaceAll(" EXTRACT(DOY FROM $1");
512  } while (!sql.equals(start));
513 
514  do {
515  start = sql;
516  sql = DAYOFWEEK.matcher(sql).replaceAll(" EXTRACT(ISODOW FROM $1");
517  } while (!sql.equals(start));
518 
519  do {
520  start = sql;
521  sql = WEEK.matcher(sql).replaceAll(" EXTRACT(WEEK FROM $1");
522  } while (!sql.equals(start));
523 
524  return sql;
525  }
526 }
auto sql(const std::string &sql_stmts)
static String fnReplace(String sql)
boolean isWrapperFor(Class<?> iface)
public< T > T unwrap(Class< T > iface)
int executeUpdate(String sql, String[] columnNames)
boolean execute(String sql, int[] columnIndexes)
OmniSciStatement(String tsession, MapD.Client tclient)
int executeUpdate(String sql, int[] columnIndexes)
boolean execute(String sql, int autoGeneratedKeys)
void setEscapeProcessing(boolean enable)
boolean execute(String sql, String[] columnNames)
int executeUpdate(String sql, int autoGeneratedKeys)