15
15
16
16
import com .google .common .collect .ImmutableSet ;
17
17
import com .google .inject .Inject ;
18
+ import io .trino .plugin .base .expression .ConnectorExpressionRewriter ;
18
19
import io .trino .plugin .base .mapping .IdentifierMapping ;
19
20
import io .trino .plugin .jdbc .BaseJdbcClient ;
20
21
import io .trino .plugin .jdbc .BaseJdbcConfig ;
31
32
import io .trino .plugin .jdbc .QueryBuilder ;
32
33
import io .trino .plugin .jdbc .WriteFunction ;
33
34
import io .trino .plugin .jdbc .WriteMapping ;
35
+ import io .trino .plugin .jdbc .expression .JdbcConnectorExpressionRewriterBuilder ;
36
+ import io .trino .plugin .jdbc .expression .ParameterizedExpression ;
37
+ import io .trino .plugin .jdbc .expression .RewriteIn ;
34
38
import io .trino .plugin .jdbc .logging .RemoteQueryModifier ;
35
39
import io .trino .spi .TrinoException ;
36
40
import io .trino .spi .connector .AggregateFunction ;
39
43
import io .trino .spi .connector .ColumnPosition ;
40
44
import io .trino .spi .connector .ConnectorSession ;
41
45
import io .trino .spi .connector .ConnectorTableMetadata ;
46
+ import io .trino .spi .expression .ConnectorExpression ;
47
+ import io .trino .spi .type .CharType ;
48
+ import io .trino .spi .type .DecimalType ;
42
49
import io .trino .spi .type .Type ;
50
+ import io .trino .spi .type .VarcharType ;
43
51
44
52
import java .sql .Connection ;
45
53
import java .sql .Date ;
52
60
import java .util .Set ;
53
61
54
62
import static io .trino .plugin .jdbc .StandardColumnMappings .bigintColumnMapping ;
63
+ import static io .trino .plugin .jdbc .StandardColumnMappings .bigintWriteFunction ;
55
64
import static io .trino .plugin .jdbc .StandardColumnMappings .booleanColumnMapping ;
65
+ import static io .trino .plugin .jdbc .StandardColumnMappings .booleanWriteFunction ;
66
+ import static io .trino .plugin .jdbc .StandardColumnMappings .charWriteFunction ;
56
67
import static io .trino .plugin .jdbc .StandardColumnMappings .decimalColumnMapping ;
57
68
import static io .trino .plugin .jdbc .StandardColumnMappings .defaultCharColumnMapping ;
58
69
import static io .trino .plugin .jdbc .StandardColumnMappings .defaultVarcharColumnMapping ;
59
70
import static io .trino .plugin .jdbc .StandardColumnMappings .doubleColumnMapping ;
71
+ import static io .trino .plugin .jdbc .StandardColumnMappings .doubleWriteFunction ;
60
72
import static io .trino .plugin .jdbc .StandardColumnMappings .integerColumnMapping ;
73
+ import static io .trino .plugin .jdbc .StandardColumnMappings .integerWriteFunction ;
74
+ import static io .trino .plugin .jdbc .StandardColumnMappings .longDecimalWriteFunction ;
75
+ import static io .trino .plugin .jdbc .StandardColumnMappings .shortDecimalWriteFunction ;
61
76
import static io .trino .plugin .jdbc .StandardColumnMappings .smallintColumnMapping ;
77
+ import static io .trino .plugin .jdbc .StandardColumnMappings .smallintWriteFunction ;
78
+ import static io .trino .plugin .jdbc .StandardColumnMappings .tinyintWriteFunction ;
79
+ import static io .trino .plugin .jdbc .StandardColumnMappings .varcharWriteFunction ;
62
80
import static io .trino .plugin .jdbc .TypeHandlingJdbcSessionProperties .getUnsupportedTypeHandling ;
63
81
import static io .trino .plugin .jdbc .UnsupportedTypeHandling .CONVERT_TO_VARCHAR ;
64
82
import static io .trino .spi .StandardErrorCode .NOT_SUPPORTED ;
65
83
import static io .trino .spi .connector .ConnectorMetadata .MODIFYING_ROWS_MESSAGE ;
84
+ import static io .trino .spi .type .BigintType .BIGINT ;
85
+ import static io .trino .spi .type .BooleanType .BOOLEAN ;
66
86
import static io .trino .spi .type .DateType .DATE ;
67
87
import static io .trino .spi .type .DecimalType .createDecimalType ;
88
+ import static io .trino .spi .type .DoubleType .DOUBLE ;
89
+ import static io .trino .spi .type .IntegerType .INTEGER ;
90
+ import static io .trino .spi .type .SmallintType .SMALLINT ;
91
+ import static io .trino .spi .type .TinyintType .TINYINT ;
92
+ import static java .lang .String .format ;
68
93
import static java .util .Locale .ENGLISH ;
69
94
70
95
public class ExasolClient
@@ -75,6 +100,9 @@ public class ExasolClient
75
100
.add ("SYS" )
76
101
.build ();
77
102
103
+ private final ConnectorExpressionRewriter <ParameterizedExpression > connectorExpressionRewriter ;
104
+ private static final int EXASOL_MAX_SUPPORTED_VARCHAR_SIZE = 20000 ;
105
+
78
106
@ Inject
79
107
public ExasolClient (
80
108
BaseJdbcConfig config ,
@@ -84,6 +112,29 @@ public ExasolClient(
84
112
RemoteQueryModifier queryModifier )
85
113
{
86
114
super ("\" " , connectionFactory , queryBuilder , config .getJdbcTypesMappedToVarchar (), identifierMapping , queryModifier , false );
115
+ this .connectorExpressionRewriter = JdbcConnectorExpressionRewriterBuilder .newBuilder ()
116
+ .addStandardRules (this ::quoted )
117
+ .add (new RewriteIn ())
118
+ .withTypeClass ("integer_type" , ImmutableSet .of ("tinyint" , "smallint" , "integer" , "bigint" ))
119
+ .withTypeClass ("numeric_type" , ImmutableSet .of ("tinyint" , "smallint" , "integer" , "bigint" , "decimal" , "real" , "double" ))
120
+ .map ("$equal(left, right)" ).to ("left = right" )
121
+ .map ("$not_equal(left, right)" ).to ("left <> right" )
122
+ .map ("$less_than(left, right)" ).to ("left < right" )
123
+ .map ("$less_than_or_equal(left, right)" ).to ("left <= right" )
124
+ .map ("$greater_than(left, right)" ).to ("left > right" )
125
+ .map ("$greater_than_or_equal(left, right)" ).to ("left >= right" )
126
+ .map ("$add(left: integer_type, right: integer_type)" ).to ("left + right" )
127
+ .map ("$subtract(left: integer_type, right: integer_type)" ).to ("left - right" )
128
+ .map ("$multiply(left: integer_type, right: integer_type)" ).to ("left * right" )
129
+ .map ("$divide(left: integer_type, right: integer_type)" ).to ("left / right" )
130
+ .map ("$modulus(left: integer_type, right: integer_type)" ).to ("left % right" )
131
+ .map ("$negate(value: integer_type)" ).to ("-value" )
132
+ .map ("$like(value: varchar, pattern: varchar): boolean" ).to ("value LIKE pattern" )
133
+ .map ("$not($is_null(value))" ).to ("value IS NOT NULL" )
134
+ .map ("$not(value: boolean)" ).to ("NOT value" )
135
+ .map ("$is_null(value)" ).to ("value IS NULL" )
136
+ .map ("$nullif(first, second)" ).to ("NULLIF(first, second)" )
137
+ .build ();
87
138
}
88
139
89
140
@ Override
@@ -95,6 +146,12 @@ protected boolean filterSchema(String schemaName)
95
146
return super .filterSchema (schemaName );
96
147
}
97
148
149
+ @ Override
150
+ public Optional <ParameterizedExpression > convertPredicate (ConnectorSession session , ConnectorExpression expression , Map <String , ColumnHandle > assignments )
151
+ {
152
+ return connectorExpressionRewriter .rewrite (session , expression , assignments );
153
+ }
154
+
98
155
@ Override
99
156
public OptionalLong delete (ConnectorSession session , JdbcTableHandle handle )
100
157
{
@@ -188,8 +245,7 @@ protected void renameTable(ConnectorSession session, Connection connection, Stri
188
245
@ Override
189
246
protected boolean isSupportedJoinCondition (ConnectorSession session , JdbcJoinCondition joinCondition )
190
247
{
191
- // Deactivated because test 'testJoinPushdown()' requires write access which is not implemented for Exasol
192
- return false ;
248
+ return true ;
193
249
}
194
250
195
251
@ Override
@@ -265,7 +321,48 @@ private static LongWriteFunction dateWriteFunctionUsingSqlDate()
265
321
@ Override
266
322
public WriteMapping toWriteMapping (ConnectorSession session , Type type )
267
323
{
268
- throw new TrinoException (NOT_SUPPORTED , "This connector does not support writing" );
324
+ if (type == BOOLEAN ) {
325
+ return WriteMapping .booleanMapping ("boolean" , booleanWriteFunction ());
326
+ }
327
+
328
+ if (type == TINYINT ) {
329
+ return WriteMapping .longMapping ("tinyint" , tinyintWriteFunction ());
330
+ }
331
+ if (type == SMALLINT ) {
332
+ return WriteMapping .longMapping ("smallint" , smallintWriteFunction ());
333
+ }
334
+ if (type == INTEGER ) {
335
+ return WriteMapping .longMapping ("integer" , integerWriteFunction ());
336
+ }
337
+ if (type == BIGINT ) {
338
+ return WriteMapping .longMapping ("bigint" , bigintWriteFunction ());
339
+ }
340
+
341
+ if (type == DOUBLE ) {
342
+ return WriteMapping .doubleMapping ("double" , doubleWriteFunction ());
343
+ }
344
+
345
+ if (type instanceof DecimalType decimalType ) {
346
+ String dataType = format ("decimal(%s, %s)" , decimalType .getPrecision (), decimalType .getScale ());
347
+ if (decimalType .isShort ()) {
348
+ return WriteMapping .longMapping (dataType , shortDecimalWriteFunction (decimalType ));
349
+ }
350
+ return WriteMapping .objectMapping (dataType , longDecimalWriteFunction (decimalType ));
351
+ }
352
+
353
+ if (type instanceof CharType charType ) {
354
+ return WriteMapping .sliceMapping ("char(" + charType .getLength () + ")" , charWriteFunction ());
355
+ }
356
+
357
+ if (type instanceof VarcharType varcharType ) {
358
+ int length = varcharType .isUnbounded ()
359
+ ? EXASOL_MAX_SUPPORTED_VARCHAR_SIZE
360
+ : Math .min (varcharType .getBoundedLength (), EXASOL_MAX_SUPPORTED_VARCHAR_SIZE );
361
+ String dataType = "varchar(" + length + ")" ;
362
+ return WriteMapping .sliceMapping (dataType , varcharWriteFunction ());
363
+ }
364
+
365
+ throw new TrinoException (NOT_SUPPORTED , "Unsupported column type: " + type .getDisplayName ());
269
366
}
270
367
271
368
@ Override
0 commit comments