forked from h2database/h2database
/
Mode.java
740 lines (639 loc) · 23.8 KB
/
Mode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
/*
* Copyright 2004-2022 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.engine;
import java.sql.Types;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
import java.util.regex.Pattern;
import org.h2.util.StringUtils;
import org.h2.value.DataType;
import org.h2.value.Value;
/**
* The compatibility modes. There is a fixed set of modes (for example
* PostgreSQL, MySQL). Each mode has different settings.
*/
public class Mode {
public enum ModeEnum {
REGULAR, STRICT, LEGACY, DB2, Derby, MariaDB, MSSQLServer, HSQLDB, MySQL, Oracle, PostgreSQL
}
/**
* Determines how rows with {@code NULL} values in indexed columns are handled
* in unique indexes.
*/
public enum UniqueIndexNullsHandling {
/**
* Multiple rows with identical values in indexed columns with at least one
* indexed {@code NULL} value are allowed in unique index.
*/
ALLOW_DUPLICATES_WITH_ANY_NULL,
/**
* Multiple rows with identical values in indexed columns with all indexed
* {@code NULL} values are allowed in unique index.
*/
ALLOW_DUPLICATES_WITH_ALL_NULLS,
/**
* Multiple rows with identical values in indexed columns are not allowed in
* unique index.
*/
FORBID_ANY_DUPLICATES
}
/**
* Generation of column names for expressions.
*/
public enum ExpressionNames {
/**
* Use optimized SQL representation of expression.
*/
OPTIMIZED_SQL,
/**
* Use original SQL representation of expression.
*/
ORIGINAL_SQL,
/**
* Generate empty name.
*/
EMPTY,
/**
* Use ordinal number of a column.
*/
NUMBER,
/**
* Use ordinal number of a column with C prefix.
*/
C_NUMBER,
/**
* Use function name for functions and ?column? for other expressions
*/
POSTGRESQL_STYLE,
}
/**
* Generation of column names for expressions to be used in a view.
*/
public enum ViewExpressionNames {
/**
* Use both specified and generated names as is.
*/
AS_IS,
/**
* Throw exception for unspecified names.
*/
EXCEPTION,
/**
* Use both specified and generated names as is, but replace too long
* generated names with {@code Name_exp_###}.
*/
MYSQL_STYLE,
}
/**
* When CHAR values are right-padded with spaces.
*/
public enum CharPadding {
/**
* CHAR values are always right-padded with spaces.
*/
ALWAYS,
/**
* Spaces are trimmed from the right side of CHAR values, but CHAR
* values in result sets are right-padded with spaces to the declared
* length
*/
IN_RESULT_SETS,
/**
* Spaces are trimmed from the right side of CHAR values.
*/
NEVER
}
private static final HashMap<String, Mode> MODES = new HashMap<>();
// Modes are also documented in the features section
/**
* When enabled, aliased columns (as in SELECT ID AS I FROM TEST) return the
* alias (I in this case) in ResultSetMetaData.getColumnName() and 'null' in
* getTableName(). If disabled, the real column name (ID in this case) and
* table name is returned.
*/
public boolean aliasColumnName;
/**
* When converting the scale of decimal data, the number is only converted
* if the new scale is smaller than the current scale. Usually, the scale is
* converted and 0s are added if required.
*/
public boolean convertOnlyToSmallerScale;
/**
* Creating indexes in the CREATE TABLE statement is allowed using
* <code>INDEX(..)</code> or <code>KEY(..)</code>.
* Example: <code>create table test(id int primary key, name varchar(255),
* key idx_name(name));</code>
*/
public boolean indexDefinitionInCreateTable;
/**
* Identifiers may be quoted using square brackets as in [Test].
*/
public boolean squareBracketQuotedNames;
/**
* The system columns 'ctid' and 'oid' are supported.
*/
public boolean systemColumns;
/**
* Determines how rows with {@code NULL} values in indexed columns are handled
* in unique indexes.
*/
public UniqueIndexNullsHandling uniqueIndexNullsHandling = UniqueIndexNullsHandling.ALLOW_DUPLICATES_WITH_ANY_NULL;
/**
* Empty strings are treated like NULL values. Useful for Oracle emulation.
*/
public boolean treatEmptyStringsAsNull;
/**
* Support the pseudo-table SYSIBM.SYSDUMMY1.
*/
public boolean sysDummy1;
/**
* Text can be concatenated using '+'.
*/
public boolean allowPlusForStringConcat;
/**
* The single-argument function LOG() uses base 10 instead of E.
*/
public boolean logIsLogBase10;
/**
* Swap the parameters of LOG() function.
*/
public boolean swapLogFunctionParameters;
/**
* The function REGEXP_REPLACE() uses \ for back-references.
*/
public boolean regexpReplaceBackslashReferences;
/**
* Swap the parameters of the CONVERT function.
*/
public boolean swapConvertFunctionParameters;
/**
* can set the isolation level using WITH {RR|RS|CS|UR}
*/
public boolean isolationLevelInSelectOrInsertStatement;
/**
* MySQL style INSERT ... ON DUPLICATE KEY UPDATE ... and INSERT IGNORE.
*/
public boolean onDuplicateKeyUpdate;
/**
* MySQL style REPLACE INTO.
*/
public boolean replaceInto;
/**
* PostgreSQL style INSERT ... ON CONFLICT DO NOTHING.
*/
public boolean insertOnConflict;
/**
* Pattern describing the keys the java.sql.Connection.setClientInfo()
* method accepts.
*/
public Pattern supportedClientInfoPropertiesRegEx;
/**
* Support the # for column names
*/
public boolean supportPoundSymbolForColumnNames;
/**
* Whether IN predicate may have an empty value list.
*/
public boolean allowEmptyInPredicate;
/**
* How to pad or trim CHAR values.
*/
public CharPadding charPadding = CharPadding.ALWAYS;
/**
* Whether DB2 TIMESTAMP formats are allowed.
*/
public boolean allowDB2TimestampFormat;
/**
* Discard SQLServer table hints (e.g. "SELECT * FROM table WITH (NOLOCK)")
*/
public boolean discardWithTableHints;
/**
* If {@code true}, datetime value function return the same value within a
* transaction, if {@code false} datetime value functions return the same
* value within a command.
*/
public boolean dateTimeValueWithinTransaction;
/**
* If {@code true} {@code 0x}-prefixed numbers are parsed as binary string
* literals, if {@code false} they are parsed as hexadecimal numeric values.
*/
public boolean zeroExLiteralsAreBinaryStrings;
/**
* If {@code true} unrelated ORDER BY expression are allowed in DISTINCT
* queries, if {@code false} they are disallowed.
*/
public boolean allowUnrelatedOrderByExpressionsInDistinctQueries;
/**
* If {@code true} some additional non-standard ALTER TABLE commands are allowed.
*/
public boolean alterTableExtensionsMySQL;
/**
* If {@code true} non-standard ALTER TABLE MODIFY COLUMN is allowed.
*/
public boolean alterTableModifyColumn;
/**
* If {@code true} TRUNCATE TABLE uses RESTART IDENTITY by default.
*/
public boolean truncateTableRestartIdentity;
/**
* If {@code true} NEXT VALUE FOR SEQUENCE, CURRENT VALUE FOR SEQUENCE,
* SEQUENCE.NEXTVAL, and SEQUENCE.CURRVAL return values with DECIMAL/NUMERIC
* data type instead of BIGINT.
*/
public boolean decimalSequences;
/**
* If {@code true} constructs like 'CREATE TABLE CATALOG..TABLE_NAME' are allowed,
* the default schema is used.
*/
public boolean allowEmptySchemaValuesAsDefaultSchema;
/**
* If {@code true} all numeric data types may have precision and 'UNSIGNED'
* clause.
*/
public boolean allNumericTypesHavePrecision;
/**
* If {@code true} 'FOR BIT DATA' clauses are allowed for character string
* data types.
*/
public boolean forBitData;
/**
* If {@code true} 'CHAR' and 'BYTE' length units are allowed.
*/
public boolean charAndByteLengthUnits;
/**
* If {@code true}, sequence.NEXTVAL and sequence.CURRVAL pseudo columns are
* supported.
*/
public boolean nextvalAndCurrvalPseudoColumns;
/**
* If {@code true}, the next value expression returns different values when
* invoked multiple times within a row. This setting does not affect
* NEXTVAL() function.
*/
public boolean nextValueReturnsDifferentValues;
/**
* If {@code true}, sequences of generated by default identity columns are
* updated when value is provided by user.
*/
public boolean updateSequenceOnManualIdentityInsertion;
/**
* If {@code true}, last identity of the session is updated on insertion of
* a new value into identity column.
*/
public boolean takeInsertedIdentity;
/**
* If {@code true}, last identity of the session is updated on generation of
* a new sequence value.
*/
public boolean takeGeneratedSequenceValue;
/**
* If {@code true}, identity columns have DEFAULT ON NULL clause.
*/
public boolean identityColumnsHaveDefaultOnNull;
/**
* If {@code true}, merge when matched clause may have WHERE clause.
*/
public boolean mergeWhere;
/**
* If {@code true}, allow using from clause in update statement.
*/
public boolean allowUsingFromClauseInUpdateStatement;
/**
* If {@code true}, referential constraints will create a unique constraint
* on referenced columns if it doesn't exist instead of throwing an
* exception.
*/
public boolean createUniqueConstraintForReferencedColumns;
/**
* How column names are generated for expressions.
*/
public ExpressionNames expressionNames = ExpressionNames.OPTIMIZED_SQL;
/**
* How column names are generated for views.
*/
public ViewExpressionNames viewExpressionNames = ViewExpressionNames.AS_IS;
/**
* Whether TOP clause in SELECT queries is supported.
*/
public boolean topInSelect;
/**
* Whether TOP clause in DML commands is supported.
*/
public boolean topInDML;
/**
* Whether LIMIT / OFFSET clauses are supported.
*/
public boolean limit;
/**
* Whether MINUS can be used as EXCEPT.
*/
public boolean minusIsExcept;
/**
* Whether IDENTITY pseudo data type is supported.
*/
public boolean identityDataType;
/**
* Whether SERIAL and BIGSERIAL pseudo data types are supported.
*/
public boolean serialDataTypes;
/**
* Whether SQL Server-style IDENTITY clause is supported.
*/
public boolean identityClause;
/**
* Whether MySQL-style AUTO_INCREMENT clause is supported.
*/
public boolean autoIncrementClause;
/**
* Whether DATE data type is parsed as TIMESTAMP(0).
*/
public boolean dateIsTimestamp0;
/**
* Whether NUMERIC and DECIMAL/DEC without parameters are parsed as DECFLOAT.
*/
public boolean numericIsDecfloat;
/**
* An optional Set of hidden/disallowed column types.
* Certain DBMSs don't support all column types provided by H2, such as
* "NUMBER" when using PostgreSQL mode.
*/
public Set<String> disallowedTypes = Collections.emptySet();
/**
* Custom mappings from type names to data types.
*/
public HashMap<String, DataType> typeByNameMap = new HashMap<>();
/**
* Allow to use GROUP BY n, where n is column index in the SELECT list, similar to ORDER BY
*/
public boolean groupByColumnIndex;
/**
* Allow to compare numeric with BOOLEAN.
*/
public boolean numericWithBooleanComparison;
private final String name;
private final ModeEnum modeEnum;
static {
Mode mode = new Mode(ModeEnum.REGULAR);
mode.allowEmptyInPredicate = true;
mode.dateTimeValueWithinTransaction = true;
mode.topInSelect = true;
mode.limit = true;
mode.minusIsExcept = true;
mode.identityDataType = true;
mode.serialDataTypes = true;
mode.autoIncrementClause = true;
add(mode);
mode = new Mode(ModeEnum.STRICT);
mode.dateTimeValueWithinTransaction = true;
add(mode);
mode = new Mode(ModeEnum.LEGACY);
// Features of REGULAR mode
mode.allowEmptyInPredicate = true;
mode.dateTimeValueWithinTransaction = true;
mode.topInSelect = true;
mode.limit = true;
mode.minusIsExcept = true;
mode.identityDataType = true;
mode.serialDataTypes = true;
mode.autoIncrementClause = true;
// Legacy identity and sequence features
mode.identityClause = true;
mode.updateSequenceOnManualIdentityInsertion = true;
mode.takeInsertedIdentity = true;
mode.identityColumnsHaveDefaultOnNull = true;
mode.nextvalAndCurrvalPseudoColumns = true;
// Legacy DML features
mode.topInDML = true;
mode.mergeWhere = true;
// Legacy DDL features
mode.createUniqueConstraintForReferencedColumns = true;
// Legacy numeric with boolean comparison
mode.numericWithBooleanComparison = true;
add(mode);
mode = new Mode(ModeEnum.DB2);
mode.aliasColumnName = true;
mode.sysDummy1 = true;
mode.isolationLevelInSelectOrInsertStatement = true;
// See
// https://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/
// com.ibm.db2z11.doc.java/src/tpc/imjcc_r0052001.dita
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile("ApplicationName|ClientAccountingInformation|" +
"ClientUser|ClientCorrelationToken");
mode.allowDB2TimestampFormat = true;
mode.forBitData = true;
mode.takeInsertedIdentity = true;
mode.nextvalAndCurrvalPseudoColumns = true;
mode.expressionNames = ExpressionNames.NUMBER;
mode.viewExpressionNames = ViewExpressionNames.EXCEPTION;
mode.limit = true;
mode.minusIsExcept = true;
mode.numericWithBooleanComparison = true;
add(mode);
mode = new Mode(ModeEnum.Derby);
mode.aliasColumnName = true;
mode.uniqueIndexNullsHandling = UniqueIndexNullsHandling.FORBID_ANY_DUPLICATES;
mode.sysDummy1 = true;
mode.isolationLevelInSelectOrInsertStatement = true;
// Derby does not support client info properties as of version 10.12.1.1
mode.supportedClientInfoPropertiesRegEx = null;
mode.forBitData = true;
mode.takeInsertedIdentity = true;
mode.expressionNames = ExpressionNames.NUMBER;
mode.viewExpressionNames = ViewExpressionNames.EXCEPTION;
add(mode);
mode = new Mode(ModeEnum.HSQLDB);
mode.allowPlusForStringConcat = true;
mode.identityColumnsHaveDefaultOnNull = true;
// HSQLDB does not support client info properties. See
// http://hsqldb.org/doc/apidocs/org/hsqldb/jdbc/JDBCConnection.html#setClientInfo-java.lang.String-java.lang.String-
mode.supportedClientInfoPropertiesRegEx = null;
mode.expressionNames = ExpressionNames.C_NUMBER;
mode.topInSelect = true;
mode.limit = true;
mode.minusIsExcept = true;
mode.numericWithBooleanComparison = true;
add(mode);
mode = new Mode(ModeEnum.MSSQLServer);
mode.aliasColumnName = true;
mode.squareBracketQuotedNames = true;
mode.uniqueIndexNullsHandling = UniqueIndexNullsHandling.FORBID_ANY_DUPLICATES;
mode.allowPlusForStringConcat = true;
mode.swapLogFunctionParameters = true;
mode.swapConvertFunctionParameters = true;
mode.supportPoundSymbolForColumnNames = true;
mode.discardWithTableHints = true;
// MS SQL Server does not support client info properties. See
// https://msdn.microsoft.com/en-Us/library/dd571296%28v=sql.110%29.aspx
mode.supportedClientInfoPropertiesRegEx = null;
mode.zeroExLiteralsAreBinaryStrings = true;
mode.truncateTableRestartIdentity = true;
mode.takeInsertedIdentity = true;
DataType dt = DataType.createNumeric(19, 4);
dt.type = Value.NUMERIC;
dt.sqlType = Types.NUMERIC;
dt.specialPrecisionScale = true;
mode.typeByNameMap.put("MONEY", dt);
dt = DataType.createNumeric(10, 4);
dt.type = Value.NUMERIC;
dt.sqlType = Types.NUMERIC;
dt.specialPrecisionScale = true;
mode.typeByNameMap.put("SMALLMONEY", dt);
mode.typeByNameMap.put("UNIQUEIDENTIFIER", DataType.getDataType(Value.UUID));
mode.allowEmptySchemaValuesAsDefaultSchema = true;
mode.expressionNames = ExpressionNames.EMPTY;
mode.viewExpressionNames = ViewExpressionNames.EXCEPTION;
mode.topInSelect = true;
mode.topInDML = true;
mode.identityClause = true;
mode.numericWithBooleanComparison = true;
add(mode);
mode = new Mode(ModeEnum.MariaDB);
mode.indexDefinitionInCreateTable = true;
mode.regexpReplaceBackslashReferences = true;
mode.onDuplicateKeyUpdate = true;
mode.replaceInto = true;
mode.charPadding = CharPadding.NEVER;
mode.supportedClientInfoPropertiesRegEx = Pattern.compile(".*");
mode.zeroExLiteralsAreBinaryStrings = true;
mode.allowUnrelatedOrderByExpressionsInDistinctQueries = true;
mode.alterTableExtensionsMySQL = true;
mode.alterTableModifyColumn = true;
mode.truncateTableRestartIdentity = true;
mode.allNumericTypesHavePrecision = true;
mode.nextValueReturnsDifferentValues = true;
mode.updateSequenceOnManualIdentityInsertion = true;
mode.takeInsertedIdentity = true;
mode.identityColumnsHaveDefaultOnNull = true;
mode.expressionNames = ExpressionNames.ORIGINAL_SQL;
mode.viewExpressionNames = ViewExpressionNames.MYSQL_STYLE;
mode.limit = true;
mode.autoIncrementClause = true;
mode.typeByNameMap.put("YEAR", DataType.getDataType(Value.SMALLINT));
mode.groupByColumnIndex = true;
mode.numericWithBooleanComparison = true;
add(mode);
mode = new Mode(ModeEnum.MySQL);
mode.indexDefinitionInCreateTable = true;
mode.regexpReplaceBackslashReferences = true;
mode.onDuplicateKeyUpdate = true;
mode.replaceInto = true;
mode.charPadding = CharPadding.NEVER;
// MySQL allows to use any key for client info entries. See
// https://github.com/mysql/mysql-connector-j/blob/5.1.47/src/com/mysql/jdbc/JDBC4CommentClientInfoProvider.java
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile(".*");
mode.zeroExLiteralsAreBinaryStrings = true;
mode.allowUnrelatedOrderByExpressionsInDistinctQueries = true;
mode.alterTableExtensionsMySQL = true;
mode.alterTableModifyColumn = true;
mode.truncateTableRestartIdentity = true;
mode.allNumericTypesHavePrecision = true;
mode.updateSequenceOnManualIdentityInsertion = true;
mode.takeInsertedIdentity = true;
mode.identityColumnsHaveDefaultOnNull = true;
mode.createUniqueConstraintForReferencedColumns = true;
mode.expressionNames = ExpressionNames.ORIGINAL_SQL;
mode.viewExpressionNames = ViewExpressionNames.MYSQL_STYLE;
mode.limit = true;
mode.autoIncrementClause = true;
mode.typeByNameMap.put("YEAR", DataType.getDataType(Value.SMALLINT));
mode.groupByColumnIndex = true;
mode.numericWithBooleanComparison = true;
add(mode);
mode = new Mode(ModeEnum.Oracle);
mode.aliasColumnName = true;
mode.convertOnlyToSmallerScale = true;
mode.uniqueIndexNullsHandling = UniqueIndexNullsHandling.ALLOW_DUPLICATES_WITH_ALL_NULLS;
mode.treatEmptyStringsAsNull = true;
mode.regexpReplaceBackslashReferences = true;
mode.supportPoundSymbolForColumnNames = true;
// Oracle accepts keys of the form <namespace>.*. See
// https://docs.oracle.com/database/121/JJDBC/jdbcvers.htm#JJDBC29006
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile(".*\\..*");
mode.alterTableModifyColumn = true;
mode.decimalSequences = true;
mode.charAndByteLengthUnits = true;
mode.nextvalAndCurrvalPseudoColumns = true;
mode.mergeWhere = true;
mode.minusIsExcept = true;
mode.expressionNames = ExpressionNames.ORIGINAL_SQL;
mode.viewExpressionNames = ViewExpressionNames.EXCEPTION;
mode.dateIsTimestamp0 = true;
mode.typeByNameMap.put("BINARY_FLOAT", DataType.getDataType(Value.REAL));
mode.typeByNameMap.put("BINARY_DOUBLE", DataType.getDataType(Value.DOUBLE));
add(mode);
mode = new Mode(ModeEnum.PostgreSQL);
mode.aliasColumnName = true;
mode.systemColumns = true;
mode.logIsLogBase10 = true;
mode.regexpReplaceBackslashReferences = true;
mode.insertOnConflict = true;
// PostgreSQL only supports the ApplicationName property. See
// https://github.com/hhru/postgres-jdbc/blob/master/postgresql-jdbc-9.2-1002.src/
// org/postgresql/jdbc4/AbstractJdbc4Connection.java
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile("ApplicationName");
mode.charPadding = CharPadding.IN_RESULT_SETS;
mode.nextValueReturnsDifferentValues = true;
mode.takeGeneratedSequenceValue = true;
mode.expressionNames = ExpressionNames.POSTGRESQL_STYLE;
mode.allowUsingFromClauseInUpdateStatement = true;
mode.limit = true;
mode.serialDataTypes = true;
mode.numericIsDecfloat = true;
// Enumerate all H2 types NOT supported by PostgreSQL:
Set<String> disallowedTypes = new java.util.HashSet<>();
disallowedTypes.add("NUMBER");
disallowedTypes.add("TINYINT");
disallowedTypes.add("BLOB");
disallowedTypes.add("VARCHAR_IGNORECASE");
mode.disallowedTypes = disallowedTypes;
dt = DataType.getDataType(Value.JSON);
mode.typeByNameMap.put("JSONB", dt);
dt = DataType.createNumeric(19, 2);
dt.type = Value.NUMERIC;
dt.sqlType = Types.NUMERIC;
dt.specialPrecisionScale = true;
mode.typeByNameMap.put("MONEY", dt);
dt = DataType.getDataType(Value.INTEGER);
mode.typeByNameMap.put("OID", dt);
mode.dateTimeValueWithinTransaction = true;
mode.groupByColumnIndex = true;
add(mode);
}
private Mode(ModeEnum modeEnum) {
this.name = modeEnum.name();
this.modeEnum = modeEnum;
}
private static void add(Mode mode) {
MODES.put(StringUtils.toUpperEnglish(mode.name), mode);
}
/**
* Get the mode with the given name.
*
* @param name the name of the mode
* @return the mode object
*/
public static Mode getInstance(String name) {
return MODES.get(StringUtils.toUpperEnglish(name));
}
public static Mode getRegular() {
return getInstance(ModeEnum.REGULAR.name());
}
public String getName() {
return name;
}
public ModeEnum getEnum() {
return this.modeEnum;
}
@Override
public String toString() {
return name;
}
}