• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

torand / FasterSQL / 17012572989

16 Aug 2025 08:26PM UTC coverage: 68.265% (-0.008%) from 68.273%
17012572989

push

github

torand
refactor: sonar cloud issues

299 of 598 branches covered (50.0%)

Branch coverage included in aggregate %.

33 of 47 new or added lines in 18 files covered. (70.21%)

1 existing line in 1 file now uncovered.

1680 of 2301 relevant lines covered (73.01%)

3.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.61
/src/main/java/io/github/torand/fastersql/dialect/H2Dialect.java
1
/*
2
 * Copyright (c) 2024-2025 Tore Eide Andersen
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 io.github.torand.fastersql.dialect;
17

18
import io.github.torand.fastersql.function.singlerow.cast.DataType;
19
import io.github.torand.fastersql.statement.FasterSQLException;
20

21
import java.sql.Connection;
22
import java.sql.PreparedStatement;
23
import java.sql.SQLException;
24
import java.util.EnumSet;
25
import java.util.List;
26
import java.util.Optional;
27

28
import static io.github.torand.fastersql.dialect.Capability.CONCAT_OPERATOR;
29
import static io.github.torand.fastersql.dialect.Capability.CURRENT_TIME;
30
import static io.github.torand.fastersql.dialect.Capability.LIMIT_OFFSET;
31
import static io.github.torand.fastersql.dialect.Capability.MODULO_OPERATOR;
32
import static io.github.torand.fastersql.dialect.Capability.NULL_ORDERING;
33
import static io.github.torand.fastersql.dialect.Capability.SELECT_FOR_UPDATE;
34
import static io.github.torand.fastersql.dialect.Capability.SET_OPERATION_PARENTHESES;
35
import static io.github.torand.fastersql.dialect.Capability.TRUNCATE_TABLE;
36

37
/**
38
 * Defines the <a href="https://www.h2database.com/html/grammar.html">H2</a> SQL dialect.
39
 */
40
public class H2Dialect implements Dialect {
41
    private static final EnumSet<Capability> SUPPORTED_CAPS = EnumSet.of(LIMIT_OFFSET, CONCAT_OPERATOR, MODULO_OPERATOR, CURRENT_TIME, NULL_ORDERING, SELECT_FOR_UPDATE, TRUNCATE_TABLE, SET_OPERATION_PARENTHESES);
34✔
42

43
    /**
44
     * Creates a H2 {@link Dialect} implementation.
45
     */
46
    public H2Dialect() {
2✔
47
        // Default constructor required by Javadoc
48
    }
1✔
49

50
    @Override
51
    public String getProductName() {
52
        return "H2";
2✔
53
    }
54

55
    @Override
56
    public boolean offsetBeforeLimit() {
57
        return false;
2✔
58
    }
59

60
    @Override
61
    public Optional<String> formatRowOffsetClause() {
62
        return Optional.of("offset ?");
3✔
63
    }
64

65
    @Override
66
    public Optional<String> formatRowLimitClause() {
67
        return Optional.of("limit ?");
3✔
68
    }
69

70
    @Override
71
    public Optional<String> formatRowNumLiteral() {
72
        return Optional.of("rownum()");
×
73
    }
74

75
    @Override
76
    public String formatToNumberFunction(String operand, int precision, int scale) {
77
        return "to_number(" + operand + ")";
3✔
78
    }
79

80
    @Override
81
    public String formatToCharFunction(String operand, String format) {
82
        return "to_char(" + operand + ", " + format + ")";
4✔
83
    }
84

85
    @Override
86
    public String formatSubstringFunction(String operand, int startPos, int length) {
87
        return "substring(" + operand + ", " + startPos + ", " + length + ")";
5✔
88
    }
89

90
    @Override
91
    public String formatConcatFunction(List<String> operands) {
92
        throw new UnsupportedOperationException("H2 does not support the concat() function (use the concat infix operator instead)");
×
93
    }
94

95
    @Override
96
    public String formatLengthFunction(String operand) {
97
        return "char_length(" + operand + ")";
3✔
98
    }
99

100
    @Override
101
    public String formatCeilFunction(String operand) {
102
        return "ceiling(" + operand + ")";
3✔
103
    }
104

105
    @Override
106
    public String formatLnFunction(String operand) {
107
        return "ln(" + operand + ")";
3✔
108
    }
109

110
    @Override
111
    public String formatRoundFunction(String operand) {
112
        return "round(" + operand + ")";
3✔
113
    }
114

115
    @Override
116
    public String formatModuloFunction(String divisor, String dividend) {
117
        throw new UnsupportedOperationException("H2 does not support the mod() function (use the modulo infix operator instead)");
×
118
    }
119

120
    @Override
121
    public String formatCurrentDateFunction() {
122
        return "current_date";
2✔
123
    }
124

125
    @Override
126
    public Optional<String> getDataType(DataType dataType) {
127
        // https://www.h2database.com/html/datatypes.html
128
        return Optional.ofNullable(switch(dataType.getIsoDataType()) {
8!
129
            case BOOLEAN -> "boolean";
×
130
            case CHAR -> "char";
×
131
            case VARCHAR -> "varchar";
2✔
132
            case BIT, BIT_VARYING -> null;
×
133
            case NUMERIC -> "numeric";
×
134
            case DECIMAL -> "decimal";
2✔
135
            case INTEGER -> "integer";
×
136
            case SMALLINT -> "smallint";
×
137
            case FLOAT, DOUBLE_PRECISION -> "float";
×
138
            case REAL -> "real";
×
139
            case DATE -> "date";
×
140
            case TIME -> "time";
×
141
            case INTERVAL -> "interval";
×
142
            case CHARACTER_LARGE_OBJECT -> "clob";
×
143
            case BINARY_LARGE_OBJECT -> "blob";
×
144
        });
145
    }
146

147
    @Override
148
    public Optional<String> getConcatOperator() {
149
        return Optional.of("||");
3✔
150
    }
151

152
    @Override
153
    public boolean supports(Capability capability) {
154
        return SUPPORTED_CAPS.contains(capability);
4✔
155
    }
156

157
    /**
158
     * Adds some user defined functions emulating common SQL constructs not supported by default.
159
     * @param connection a live H2 connection.
160
     * @return the modified dialect.
161
     */
162
    public H2Dialect withCustomizations(Connection connection) {
163
        String source = """
2✔
164
            import java.lang.*;
165
            @CODE
166
            Double toNumber(String value) throws Exception {
167
                return value == null ? null : Double.valueOf(value);
168
            }
169
            """;
170

171
        try (PreparedStatement preparedStatement = connection.prepareStatement("CREATE ALIAS IF NOT EXISTS TO_NUMBER AS '%s'".formatted(source))) {
11✔
172
            preparedStatement.execute();
3✔
173
            return this;
4✔
174
        } catch (SQLException e) {
×
NEW
175
            throw new FasterSQLException("Failed to setup H2 customizations", e);
×
176
        }
177
    }
178
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc