1 /*
2  * Copyright 2015-2018 HuntLabs.cn
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 module hunt.sql.SQLTransformUtils;
17 
18 import hunt.sql.ast.SQLDataType;
19 import hunt.sql.ast.SQLDataTypeImpl;
20 import hunt.sql.ast.SQLExpr;
21 import hunt.sql.ast.expr;
22 import hunt.sql.ast.statement;
23 // import hunt.sql.dialect.oracle.ast.clause.OracleWithSubqueryEntry;
24 // import hunt.sql.dialect.oracle.ast.expr.OracleSysdateExpr;
25 // import hunt.sql.dialect.oracle.ast.stmt;
26 import hunt.sql.util.FnvHash;
27 import hunt.String;
28 import hunt.collection;
29 import std.uni;
30 import hunt.text.Common;
31 
32 public class SQLTransformUtils {
33     public static SQLExpr transformDecode(SQLMethodInvokeExpr x) {
34         if (x is null) {
35             return null;
36         }
37         
38         if (!equalsIgnoreCase("decode",x.getMethodName())) {
39             throw new Exception(x.getMethodName());
40         }
41 
42         List!(SQLExpr) parameters = x.getParameters();
43         SQLCaseExpr caseExpr = new SQLCaseExpr();
44         caseExpr.setParent(x.getParent());
45         caseExpr.setValueExpr(parameters.get(0));
46 
47         if (parameters.size() == 4) {
48             SQLExpr param1 = parameters.get(1);
49 
50             x.setMethodName("if");
51 
52             SQLBinaryOpExpr condition;
53             if (cast(SQLNullExpr)(param1) !is null) {
54                 condition = new SQLBinaryOpExpr(parameters.get(0), SQLBinaryOperator.Is, param1);
55             } else {
56                 condition = new SQLBinaryOpExpr(parameters.get(0), SQLBinaryOperator.Equality, param1);
57             }
58             condition.setParent(x);
59             parameters.set(0, condition);
60             parameters.set(1, parameters.get(2));
61             parameters.set(2, parameters.get(3));
62             parameters.removeAt(3);
63             return x;
64         }
65 
66         for (int i = 1; i + 1 < parameters.size(); i += 2) {
67             SQLCaseExpr.Item item = new SQLCaseExpr.Item();
68             SQLExpr conditionExpr = parameters.get(i);
69 
70             item.setConditionExpr(conditionExpr);
71 
72             SQLExpr valueExpr = parameters.get(i + 1);
73 
74             if (cast(SQLMethodInvokeExpr)(valueExpr) !is null) {
75                 SQLMethodInvokeExpr methodInvokeExpr = cast(SQLMethodInvokeExpr) valueExpr;
76                 if (equalsIgnoreCase("decode",methodInvokeExpr.getMethodName())) {
77                     valueExpr = transformDecode(methodInvokeExpr);
78                 }
79             }
80 
81             item.setValueExpr(valueExpr);
82             caseExpr.addItem(item);
83         }
84 
85         if (parameters.size() % 2 == 0) {
86             SQLExpr defaultExpr = parameters.get(parameters.size() - 1);
87 
88             if (cast(SQLMethodInvokeExpr)(defaultExpr) !is null) {
89                 SQLMethodInvokeExpr methodInvokeExpr = cast(SQLMethodInvokeExpr) defaultExpr;
90                 if (equalsIgnoreCase("decode",methodInvokeExpr.getMethodName())) {
91                     defaultExpr = transformDecode(methodInvokeExpr);
92                 }
93             }
94 
95             caseExpr.setElseExpr(defaultExpr);
96         }
97 
98         caseExpr.setParent(x.getParent());
99 
100         return caseExpr;
101     }
102 
103     public static SQLDataType transformOracleToMySql(SQLDataType x) {
104          string name = x.getName();
105          long nameHash = x.nameHashCode64();
106 
107         if (name is null) {
108             return x;
109         }
110         List!(SQLExpr) argumentns = x.getArguments();
111 
112         SQLDataType dataType;
113 
114         if (nameHash == FnvHash.Constants.UROWID) {
115             int len = 4000;
116             if (argumentns.size() == 1) {
117                 SQLExpr arg0 = argumentns.get(0);
118                 if (cast(SQLIntegerExpr)(arg0) !is null) {
119                     len = (cast(SQLIntegerExpr) arg0).getNumber().intValue();
120                 }
121             }
122             dataType = new SQLDataTypeImpl("varchar", len);
123         } else if (nameHash == FnvHash.Constants.ROWID) {
124             dataType = new SQLDataTypeImpl("char", 10);
125 
126         } else if (nameHash == FnvHash.Constants.BOOLEAN) {
127             dataType = new SQLDataTypeImpl("tinyint");
128 
129         } else if (nameHash == FnvHash.Constants.INTEGER) {
130             dataType = new SQLDataTypeImpl("int");
131 
132         } else if (nameHash == FnvHash.Constants.FLOAT
133                 || nameHash == FnvHash.Constants.BINARY_FLOAT) {
134                 dataType = new SQLDataTypeImpl("float");
135 
136         } else if (nameHash == FnvHash.Constants.REAL
137                 || nameHash == FnvHash.Constants.BINARY_DOUBLE
138                 || nameHash == FnvHash.Constants.DOUBLE_PRECISION) {
139             dataType = new SQLDataTypeImpl("double");
140 
141         } else if (nameHash == FnvHash.Constants.NUMBER) {
142             if (argumentns.size() == 0) {
143                 dataType = new SQLDataTypeImpl("decimal", 38);
144             } else {
145                 SQLExpr arg0 = argumentns.get(0);
146 
147                 int precision, scale = 0;
148                 if (cast(SQLAllColumnExpr)(arg0) !is null) {
149                     precision = 9;
150                 } else {
151                     precision = (cast(SQLIntegerExpr) arg0).getNumber().intValue();
152                 }
153 
154                 if (argumentns.size() > 1) {
155                     scale = (cast(SQLIntegerExpr) argumentns.get(1)).getNumber().intValue();
156                 }
157 
158                 if (scale > precision) {
159                     if (cast(SQLAllColumnExpr)(arg0) !is null) {
160                         precision = 19;
161                         if (scale > precision) {
162                             precision = scale;
163                         }
164                     } else {
165                         precision = scale;
166                     }
167                 }
168 
169                 if (scale == 0) {
170                     if (precision < 3) {
171                         dataType = new SQLDataTypeImpl("tinyint");
172                     } else if (precision < 5) {
173                         dataType = new SQLDataTypeImpl("smallint");
174                     } else if (precision < 9) {
175                         dataType = new SQLDataTypeImpl("int");
176                     } else if (precision <= 20) {
177                         dataType = new SQLDataTypeImpl("bigint");
178                     } else {
179                         dataType = new SQLDataTypeImpl("decimal", precision);
180                     }
181                 } else {
182                     dataType = new SQLDataTypeImpl("decimal", precision, scale);
183                 }
184             }
185 
186         } else if (nameHash == FnvHash.Constants.DEC
187                 || nameHash == FnvHash.Constants.DECIMAL) {
188 
189             dataType = x.clone();
190             dataType.setName("decimal");
191 
192             int precision = 0;
193             if (argumentns.size() > 0) {
194                 precision = (cast(SQLIntegerExpr) argumentns.get(0)).getNumber().intValue();
195             }
196 
197             int scale = 0;
198             if (argumentns.size() > 1) {
199                 scale = (cast(SQLIntegerExpr) argumentns.get(1)).getNumber().intValue();
200                 if (precision < scale) {
201                     (cast(SQLIntegerExpr) dataType.getArguments().get(1)).setNumber(precision);
202                 }
203             }
204 
205 //            if (precision == 38 && scale == 0 && x.getParent(cast(SQLCastExpr)()) !is null) {
206 //                dataType.getArguments().clear();
207 //                dataType.setName("int");
208 //            }
209             /////////////////////////////////
210 
211         } else if (nameHash == FnvHash.Constants.RAW) {
212             int len;
213 
214             if (argumentns.size() == 0) {
215                 len = -1;
216             } else if (argumentns.size() == 1) {
217                 SQLExpr arg0 = argumentns.get(0);
218                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
219                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
220                 } else {
221                     throw new Exception("SQLUtils.toOracleString(x)");
222                 }
223             } else {
224                 throw new Exception("SQLUtils.toOracleString(x)");
225             }
226 
227             if (len == -1) {
228                 dataType = new SQLDataTypeImpl("binary");
229             } else if (len <= 255) {
230                 dataType = new SQLDataTypeImpl("binary", len);
231             } else {
232                 dataType = new SQLDataTypeImpl("varbinary", len);
233             }
234         } else if (nameHash == FnvHash.Constants.CHAR
235                 || nameHash == FnvHash.Constants.CHARACTER) {
236             if (argumentns.size() == 1) {
237                 SQLExpr arg0 = argumentns.get(0);
238 
239                 int len;
240                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
241                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
242                 } else {
243                     throw new Exception("SQLUtils.toOracleString(x)");
244                 }
245 
246                 if (len <= 255) {
247                     dataType = new SQLCharacterDataType("char", len);
248                 } else {
249                     dataType = new SQLCharacterDataType("varchar", len);
250                 }
251             } else if (argumentns.size() == 0) {
252                 dataType = new SQLCharacterDataType("char");
253             } else {
254                 throw new Exception("SQLUtils.toOracleString(x)");
255             }
256 
257         } else if (nameHash == FnvHash.Constants.NCHAR) {
258             if (argumentns.size() == 1) {
259                 SQLExpr arg0 = argumentns.get(0);
260 
261                 int len;
262                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
263                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
264                 } else {
265                     throw new Exception("SQLUtils.toOracleString(x)");
266                 }
267 
268                 if (len <= 255) {
269                     dataType = new SQLCharacterDataType("nchar", len);
270                 } else {
271                     dataType = new SQLCharacterDataType("nvarchar", len);
272                 }
273             } else if (argumentns.size() == 0) {
274                 dataType = new SQLCharacterDataType("nchar");
275             } else {
276                 throw new Exception("SQLUtils.toOracleString(x)");
277             }
278 
279         } else if (nameHash == FnvHash.Constants.VARCHAR2) {
280             if (argumentns.size() > 0) {
281                 int len;
282                 SQLExpr arg0 = argumentns.get(0);
283                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
284                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
285                 } else {
286                     throw new Exception("SQLUtils.toOracleString(x)");
287                 }
288                 dataType = new SQLCharacterDataType("varchar", len);
289             } else {
290                 dataType = new SQLCharacterDataType("varchar");
291             }
292 
293         } else if (nameHash == FnvHash.Constants.NVARCHAR2) {
294             if (argumentns.size() > 0) {
295                 int len;
296                 SQLExpr arg0 = argumentns.get(0);
297                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
298                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
299                 } else {
300                     throw new Exception("SQLUtils.toOracleString(x)");
301                 }
302                 dataType = new SQLCharacterDataType("nvarchar", len);
303             } else {
304                 dataType = new SQLCharacterDataType("nvarchar");
305             }
306 
307         } else if (nameHash == FnvHash.Constants.BFILE) {
308             dataType = new SQLCharacterDataType("varchar", 255);
309 
310         } else if (nameHash == FnvHash.Constants.DATE
311                 || nameHash == FnvHash.Constants.TIMESTAMP) {
312             int len = -1;
313             if (argumentns.size() > 0) {
314                 SQLExpr arg0 = argumentns.get(0);
315                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
316                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
317                 } else {
318                     throw new Exception("SQLUtils.toOracleString(x)");
319                 }
320             }
321 
322             if (len >= 0) {
323                 if (len > 6) {
324                     len = 6;
325                 }
326                 dataType = new SQLDataTypeImpl("datetime", len);
327             } else {
328                 dataType = new SQLDataTypeImpl("datetime");
329             }
330         } else if (nameHash == FnvHash.Constants.BLOB
331                 || nameHash == FnvHash.Constants.LONG_RAW) {
332             argumentns.clear();
333             dataType = new SQLDataTypeImpl("LONGBLOB");
334 
335         } else if (nameHash == FnvHash.Constants.CLOB
336                 || nameHash == FnvHash.Constants.NCLOB
337                 || nameHash == FnvHash.Constants.LONG
338                 || nameHash == FnvHash.Constants.XMLTYPE) {
339             argumentns.clear();
340             dataType = new SQLCharacterDataType("LONGTEXT");
341 
342         } else {
343             dataType = x;
344         }
345 
346         if (dataType != x) {
347             dataType.setParent(x.getParent());
348         }
349 
350         return dataType;
351     }
352 
353     public static SQLDataType transformOracleToAliyunAds(SQLDataType x) {
354          string dataTypeName = toLower(x.getName());
355         SQLDataType dataType;
356 
357         if (dataTypeName == ("varchar2")
358                 || dataTypeName == ("varchar")
359                 || dataTypeName == ("char")
360                 || dataTypeName == ("nchar")
361                 || dataTypeName == ("nvarchar")
362                 || dataTypeName == ("nvarchar2")
363                 || dataTypeName == ("clob")
364                 || dataTypeName == ("nclob")
365                 || dataTypeName == ("blob")
366                 || dataTypeName == ("long")
367                 || dataTypeName == ("long raw")
368                 || dataTypeName == ("raw")
369                 ) {
370             dataType = new SQLCharacterDataType("varchar");
371         } else if (dataTypeName == ("number")
372                 || dataTypeName == ("decimal")
373                 || dataTypeName == ("dec")
374                 || dataTypeName == ("numeric")) {
375             int scale = 0;
376             if (x.getArguments().size() > 1) {
377                 scale = (cast(SQLIntegerExpr) x.getArguments().get(1)).getNumber().intValue();
378             }
379             if (scale == 0) {
380                 dataType = new SQLDataTypeImpl("bigint");
381             } else {
382                 dataType = new SQLDataTypeImpl("double");
383             }
384         } else if (dataTypeName == ("date")
385                 || dataTypeName == ("datetime")
386                 || dataTypeName == ("timestamp")) {
387             dataType = new SQLDataTypeImpl("timestamp");
388         } else if (dataTypeName == ("float")
389                 || dataTypeName == ("binary_float")) {
390             dataType = new SQLDataTypeImpl("float");
391         } else if (dataTypeName == ("double")
392                 || dataTypeName == ("binary_double")) {
393             dataType = new SQLDataTypeImpl("double");
394         } else {
395             dataType = x;
396         }
397 
398         if (dataType != x) {
399             dataType.setParent(x.getParent());
400         }
401 
402         return dataType;
403     }
404 
405     public static SQLDataType transformOracleToPostgresql(SQLDataType x) {
406          string name = x.getName();
407          long nameHash = x.nameHashCode64();
408 
409         if (name is null) {
410             return x;
411         }
412         List!(SQLExpr) argumentns = x.getArguments();
413 
414         SQLDataType dataType;
415 
416         if (nameHash == FnvHash.Constants.UROWID) {
417             int len = 4000;
418             if (argumentns.size() == 1) {
419                 SQLExpr arg0 = argumentns.get(0);
420                 if (cast(SQLIntegerExpr)(arg0) !is null) {
421                     len = (cast(SQLIntegerExpr) arg0).getNumber().intValue();
422                 }
423             }
424             dataType = new SQLDataTypeImpl(SQLDataType.Constants.VARCHAR, len);
425         } else if (nameHash == FnvHash.Constants.ROWID) {
426             dataType = new SQLDataTypeImpl(SQLDataType.Constants.CHAR, 10);
427 
428         } else if (nameHash == FnvHash.Constants.BOOLEAN || nameHash == FnvHash.Constants.SMALLINT) {
429             dataType = new SQLDataTypeImpl(SQLDataType.Constants.SMALLINT);
430 
431         } else if (nameHash == FnvHash.Constants.INTEGER
432                 || nameHash == FnvHash.Constants.INT) {
433             dataType = new SQLDataTypeImpl(SQLDataType.Constants.DECIMAL, 38);
434 
435         } else if (nameHash == FnvHash.Constants.BINARY_FLOAT) {
436             dataType = new SQLDataTypeImpl(SQLDataType.Constants.REAL);
437 
438         } else if (nameHash == FnvHash.Constants.BINARY_DOUBLE
439                 || nameHash == FnvHash.Constants.FLOAT
440                 || nameHash == FnvHash.Constants.DOUBLE
441                 || nameHash == FnvHash.Constants.REAL
442                 || nameHash == FnvHash.Constants.DOUBLE_PRECISION) {
443             dataType = new SQLDataTypeImpl(SQLDataType.Constants.DOUBLE_PRECISION);
444 
445         } else if (nameHash == FnvHash.Constants.NUMBER) {
446             if (argumentns.size() == 0) {
447                 dataType = new SQLDataTypeImpl(SQLDataType.Constants.DECIMAL, 38);
448             } else {
449                 SQLExpr arg0 = argumentns.get(0);
450 
451                 int precision, scale = 0;
452                 if (cast(SQLAllColumnExpr)(arg0) !is null) {
453                     precision = 19;
454                     scale = -1;
455                 } else {
456                     precision = (cast(SQLIntegerExpr) arg0).getNumber().intValue();
457                 }
458 
459                 if (argumentns.size() > 1) {
460                     scale = (cast(SQLIntegerExpr) argumentns.get(1)).getNumber().intValue();
461                 }
462 
463                 if (scale > precision) {
464                     if (cast(SQLAllColumnExpr)(arg0) !is null) {
465                         precision = 19;
466                         if (scale > precision) {
467                             precision = scale;
468                         }
469                     } else {
470                         precision = scale;
471                     }
472                 }
473 
474                 if (scale == 0) {
475                     if (precision < 5) {
476                         dataType = new SQLDataTypeImpl(SQLDataType.Constants.SMALLINT);
477                     } else if (precision < 9) {
478                         dataType = new SQLDataTypeImpl(SQLDataType.Constants.INT);
479                     } else if (precision <= 20) {
480                         dataType = new SQLDataTypeImpl(SQLDataType.Constants.BIGINT);
481                     } else {
482                         dataType = new SQLDataTypeImpl(SQLDataType.Constants.DECIMAL, precision);
483                     }
484                 } else if (scale == -1) {
485                     dataType = new SQLDataTypeImpl(SQLDataType.Constants.DOUBLE_PRECISION);
486                 } else {
487                     dataType = new SQLDataTypeImpl(SQLDataType.Constants.DECIMAL, precision, scale);
488                 }
489             }
490 
491         } else if (nameHash == FnvHash.Constants.DEC
492                 || nameHash == FnvHash.Constants.DECIMAL) {
493             dataType = x.clone();
494             dataType.setName(SQLDataType.Constants.DECIMAL);
495 
496             int precision = 0;
497             if (argumentns.size() > 0) {
498                 precision = (cast(SQLIntegerExpr) argumentns.get(0)).getNumber().intValue();
499             }
500 
501             int scale = 0;
502             if (argumentns.size() > 1) {
503                 scale = (cast(SQLIntegerExpr) argumentns.get(1)).getNumber().intValue();
504                 if (precision < scale) {
505                     (cast(SQLIntegerExpr) dataType.getArguments().get(1)).setNumber(precision);
506                 }
507             }
508 
509         } else if (nameHash == FnvHash.Constants.CHARACTER) {
510             if (argumentns.size() == 1) {
511                 SQLExpr arg0 = argumentns.get(0);
512 
513                 int len;
514                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
515                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
516                 } else {
517                     throw new Exception("SQLUtils.toOracleString(x)");
518                 }
519                 dataType = new SQLCharacterDataType(SQLDataType.Constants.CHAR, len);
520             } else if (argumentns.size() == 0) {
521                 dataType = new SQLCharacterDataType(SQLDataType.Constants.CHAR);
522             } else {
523                 throw new Exception("SQLUtils.toOracleString(x)");
524             }
525         } else if (nameHash == FnvHash.Constants.CHAR) {
526             if (argumentns.size() == 1) {
527                 SQLExpr arg0 = argumentns.get(0);
528 
529                 int len;
530                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
531                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
532                 } else {
533                     throw new Exception("SQLUtils.toOracleString(x)");
534                 }
535 
536                 if (len <= 2000) {
537                     dataType = x;
538                     dataType.setName(SQLDataType.Constants.CHAR);
539                 } else {
540                     dataType = new SQLCharacterDataType(SQLDataType.Constants.TEXT);
541                 }
542             } else if (argumentns.size() == 0) {
543                 dataType = new SQLCharacterDataType(SQLDataType.Constants.CHAR);
544             } else {
545                 throw new Exception("SQLUtils.toOracleString(x)");
546             }
547         } else if (nameHash == FnvHash.Constants.NCHAR) {
548             // no changed
549             dataType = x;
550             dataType.setName(SQLDataType.Constants.NCHAR);
551         } else if (nameHash == FnvHash.Constants.VARCHAR
552                 || nameHash == FnvHash.Constants.VARCHAR2) {
553             if (argumentns.size() > 0) {
554                 int len;
555                 SQLExpr arg0 = argumentns.get(0);
556                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
557                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
558                 } else if (cast(SQLVariantRefExpr)(arg0) !is null) {
559                     len = 2000;
560                 } else {
561                     throw new Exception("SQLUtils.toOracleString(x)");
562                 }
563 
564                 if (len <= 4000) {
565                     dataType = new SQLCharacterDataType(SQLDataType.Constants.VARCHAR, len);
566                 } else {
567                     dataType = new SQLCharacterDataType(SQLDataType.Constants.TEXT);
568                 }
569             } else {
570                 dataType = new SQLCharacterDataType(SQLDataType.Constants.VARCHAR);
571             }
572 
573         } else if (nameHash == FnvHash.Constants.NVARCHAR
574                 || nameHash == FnvHash.Constants.NVARCHAR2
575                 || nameHash == FnvHash.Constants.NCHAR_VARYING) {
576             if (argumentns.size() > 0) {
577                 int len;
578                 SQLExpr arg0 = argumentns.get(0);
579                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
580                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
581                 } else {
582                     throw new Exception("SQLUtils.toOracleString(x)");
583                 }
584                 dataType = new SQLCharacterDataType(SQLDataType.Constants.VARCHAR, len);
585             } else {
586                 dataType = new SQLCharacterDataType(SQLDataType.Constants.VARCHAR);
587             }
588 
589         } else if (nameHash == FnvHash.Constants.BFILE) {
590             dataType = new SQLCharacterDataType(SQLDataType.Constants.VARCHAR, 255);
591         } else if (nameHash == FnvHash.Constants.DATE) {
592             dataType = new SQLDataTypeImpl(SQLDataType.Constants.TIMESTAMP, 0);
593         } else if (nameHash == FnvHash.Constants.TIMESTAMP) {
594             x.setName(SQLDataType.Constants.TIMESTAMP);
595             if (x.isWithLocalTimeZone()) {
596                 x.setWithLocalTimeZone(false);
597                 x.setWithTimeZone(null);
598             }
599             dataType = x;
600         } else if (nameHash == FnvHash.Constants.DATETIME) {
601             int len = -1;
602             if (argumentns.size() > 0) {
603                 SQLExpr arg0 = argumentns.get(0);
604                 if (cast(SQLNumericLiteralExpr)(arg0) !is null) {
605                     len = (cast(SQLNumericLiteralExpr) arg0).getNumber().intValue();
606                 } else {
607                     throw new Exception("SQLUtils.toOracleString(x)");
608                 }
609             }
610 
611             if (len > 0) {
612                 dataType = new SQLDataTypeImpl(SQLDataType.Constants.TIMESTAMP, len);
613             } else {
614                 dataType = new SQLDataTypeImpl(SQLDataType.Constants.TIMESTAMP);
615             }
616         } else if (nameHash == FnvHash.Constants.BLOB
617                 || nameHash == FnvHash.Constants.LONG_RAW
618                 || nameHash == FnvHash.Constants.RAW) {
619             argumentns.clear();
620             dataType = new SQLDataTypeImpl(SQLDataType.Constants.BYTEA);
621 
622         } else if (nameHash == FnvHash.Constants.CLOB
623                 || nameHash == FnvHash.Constants.NCLOB
624                 || nameHash == FnvHash.Constants.LONG) {
625             argumentns.clear();
626             dataType = new SQLCharacterDataType(SQLDataType.Constants.TEXT);
627 
628         } else if (nameHash == FnvHash.Constants.XMLTYPE) {
629             dataType = new SQLDataTypeImpl(SQLDataType.Constants.XML);
630         } else {
631             dataType = x;
632         }
633 
634         if (dataType != x) {
635             dataType.setParent(x.getParent());
636         }
637 
638         return dataType;
639     }
640 
641     public static SQLExpr transformOracleToPostgresql(SQLMethodInvokeExpr x) {
642          long nameHashCode64 = x.methodNameHashCode64();
643         List!(SQLExpr) parameters = x.getParameters();
644 
645         if (nameHashCode64 == FnvHash.Constants.SYS_GUID) {
646             SQLMethodInvokeExpr uuid_generate_v4 = new SQLMethodInvokeExpr("uuid_generate_v4");
647 
648             uuid_generate_v4.setParent(x.getParent());
649             return uuid_generate_v4;
650         }
651 
652         if (nameHashCode64 == FnvHash.Constants.TRUNC) {
653             if (parameters.size() == 1) {
654                 SQLExpr param0 = parameters.get(0);
655                 if (/*cast(OracleSysdateExpr)(param0) !is null
656                         ||*/ (cast(SQLIdentifierExpr)(param0) !is null
657                             && (cast(SQLIdentifierExpr) param0).nameHashCode64() == FnvHash.Constants.CURRENT_TIMESTAMP)) {
658                     SQLMethodInvokeExpr current_timestamp = new SQLMethodInvokeExpr("CURRENT_TIMESTAMP");
659                     current_timestamp.addParameter(new SQLIntegerExpr(0));
660 
661                     current_timestamp.setParent(x.getParent());
662                     return current_timestamp;
663                 }
664             }
665         }
666 
667         if (nameHashCode64 == FnvHash.Constants.CURRENT_TIMESTAMP) {
668             if (parameters.size() == 0 &&  cast(SQLColumnDefinition)x.getParent() !is null) {
669                 SQLDataType dataType = (cast(SQLColumnDefinition) x.getParent()).getDataType();
670                 if (dataType.nameHashCode64() == FnvHash.Constants.TIMESTAMP
671                         && dataType.getArguments().size() == 1) {
672                     x.addParameter(dataType.getArguments().get(0).clone());
673                 } else {
674                     x.addParameter(new SQLIntegerExpr(0));
675                 }
676                 return x;
677             }
678         }
679 
680         if (nameHashCode64 == FnvHash.Constants.SYSTIMESTAMP) {
681             SQLMethodInvokeExpr xx = x.clone();
682             xx.setMethodName("CURRENT_TIMESTAMP");
683             xx.setParent(x.getParent());
684             return xx;
685         }
686 
687         if (nameHashCode64 == FnvHash.Constants.USERENV) {
688             if (x.getParameters().size() == 1) {
689                 SQLExpr param0 = x.getParameters().get(0);
690                 if (cast(SQLCharExpr)(param0) !is null) {
691                     string text = (cast(SQLCharExpr) param0).getText().value();
692                     if ("SESSIONID".equalsIgnoreCase(text)) {
693                         SQLMethodInvokeExpr xx = new SQLMethodInvokeExpr();
694                         xx.setMethodName("get_session_id");
695                         xx.setParent(x.getParent());
696                         return xx;
697                     }
698                 }
699             }
700         }
701 
702         if (nameHashCode64 == FnvHash.Constants.USERENV) {
703             if (x.getParameters().size() == 1) {
704                 SQLExpr param0 = x.getParameters().get(0);
705                 if (cast(SQLCharExpr)(param0) !is null) {
706                     string text = (cast(SQLCharExpr) param0).getText().value();
707                     if ("SESSIONID".equalsIgnoreCase(text)) {
708                         SQLMethodInvokeExpr xx = new SQLMethodInvokeExpr();
709                         xx.setMethodName("get_session_id");
710                         xx.setParent(x.getParent());
711                         return xx;
712                     }
713                 }
714             }
715         }
716 
717         if (nameHashCode64 == FnvHash.Constants.NUMTODSINTERVAL) {
718             if (x.getParameters().size() == 2) {
719                 SQLExpr param0 = x.getParameters().get(0);
720                 SQLExpr param1 = x.getParameters().get(1);
721 
722                 if (cast(SQLIntegerExpr)(param0) !is null && cast(SQLCharExpr)(param1) !is null) {
723                     string text = (cast(SQLCharExpr) param1).getText().value();
724                     if ("DAY".equalsIgnoreCase(text)) {
725                         SQLIntervalExpr intervalExpr = new SQLIntervalExpr();
726                         intervalExpr.setValue(new SQLCharExpr(param0.stringof ~ " DAYS"));
727                         intervalExpr.setParent(x.getParent());
728                         return intervalExpr;
729                     }
730                 }
731             }
732         }
733 
734         return x;
735     }
736 
737     // public static SQLTableSource transformOracleToPostgresql(SQLTableSource x) {
738     //     if (cast(OracleSelectTableReference)(x) !is null) {
739     //         OracleSelectTableReference xx = cast(OracleSelectTableReference) x;
740     //         SQLExprTableSource y = new SQLExprTableSource();
741     //         xx.cloneTo(y);
742 
743     //         y.setParent(x.getParent());
744     //         return y;
745     //     }
746 
747     //     if (cast(OracleSelectJoin)(x) !is null) {
748     //         OracleSelectJoin xx = cast(OracleSelectJoin) x;
749     //         SQLJoinTableSource y = new SQLJoinTableSource();
750     //         xx.cloneTo(y);
751 
752     //         y.setLeft(transformOracleToPostgresql(y.getLeft()));
753     //         y.setRight(transformOracleToPostgresql(y.getRight()));
754 
755     //         y.setParent(x.getParent());
756     //         return y;
757     //     }
758 
759     //     if (cast(OracleSelectSubqueryTableSource)(x) !is null) {
760     //         OracleSelectSubqueryTableSource xx = cast(OracleSelectSubqueryTableSource) x;
761     //         SQLSubqueryTableSource y = new SQLSubqueryTableSource();
762     //         xx.cloneTo(y);
763 
764     //         y.setParent(x.getParent());
765     //         return y;
766     //     }
767 
768     //     if (cast(OracleWithSubqueryEntry)(x) !is null) {
769     //         SQLWithSubqueryClause.Entry entry = new SQLWithSubqueryClause.Entry();
770     //         (cast(OracleWithSubqueryEntry) x).cloneTo(entry);
771     //         entry.setParent(x.getParent());
772     //         return entry;
773     //     }
774 
775     //     return x;
776     // }
777 
778     // public static SQLSelectQueryBlock transformOracleToPostgresql(SQLSelectQueryBlock x) {
779     //     if (cast(OracleSelectQueryBlock)(x) !is null) {
780     //         OracleSelectQueryBlock xx = cast(OracleSelectQueryBlock) x;
781     //         SQLSelectQueryBlock y = new SQLSelectQueryBlock();
782     //         xx.cloneTo(y);
783     //         y.setFrom(transformOracleToPostgresql(y.getFrom()));
784 
785     //         y.setParent(x.getParent());
786     //         return y;
787     //     }
788 
789     //     return x;
790     // }
791 }