2121import org .apache .flink .core .testutils .FlinkMatchers ;
2222import org .apache .flink .table .api .DataTypes ;
2323import org .apache .flink .table .api .Schema ;
24+ import org .apache .flink .table .expressions .CallExpression ;
2425import org .apache .flink .table .expressions .ResolvedExpression ;
2526import org .apache .flink .table .expressions .utils .ResolvedExpressionMock ;
27+ import org .apache .flink .table .functions .BuiltInFunctionDefinitions ;
28+ import org .apache .flink .table .functions .FunctionIdentifier ;
2629import org .apache .flink .table .types .DataType ;
2730import org .apache .flink .table .types .logical .LocalZonedTimestampType ;
2831import org .apache .flink .table .types .logical .LogicalType ;
3942import java .util .Collections ;
4043
4144import static org .apache .flink .table .api .Expressions .callSql ;
45+ import static org .apache .flink .table .api .Expressions .sourceWatermark ;
4246import static org .apache .flink .table .types .logical .utils .LogicalTypeChecks .isProctimeAttribute ;
4347import static org .apache .flink .table .types .logical .utils .LogicalTypeChecks .isRowtimeAttribute ;
4448import static org .apache .flink .table .types .logical .utils .LogicalTypeChecks .isTimeAttribute ;
@@ -90,23 +94,21 @@ public class SchemaResolutionTest {
9094
9195 // the type of ts_ltz is TIMESTAMP_LTZ
9296 private static final String COMPUTED_SQL_WITH_TS_LTZ = "ts_ltz - INTERVAL '60' MINUTE" ;
97+
9398 private static final ResolvedExpression COMPUTED_COLUMN_RESOLVED_WITH_TS_LTZ =
9499 new ResolvedExpressionMock (DataTypes .TIMESTAMP_LTZ (3 ), () -> COMPUTED_SQL_WITH_TS_LTZ );
100+
95101 private static final String WATERMARK_SQL_WITH_TS_LTZ = "ts1 - INTERVAL '5' SECOND" ;
102+
96103 private static final ResolvedExpression WATERMARK_RESOLVED_WITH_TS_LTZ =
97104 new ResolvedExpressionMock (DataTypes .TIMESTAMP_LTZ (3 ), () -> WATERMARK_SQL_WITH_TS_LTZ );
105+
98106 private static final Schema SCHEMA_WITH_TS_LTZ =
99107 Schema .newBuilder ()
100- .primaryKeyNamed ("primary_constraint" , "id" ) // out of order
101108 .column ("id" , DataTypes .INT ().notNull ())
102- .column ("counter" , DataTypes .INT ().notNull ())
103- .column ("payload" , "ROW<name STRING, age INT, flag BOOLEAN>" )
104- .columnByMetadata ("topic" , DataTypes .STRING (), true )
105- .columnByExpression (
106- "ts1" , callSql (COMPUTED_SQL_WITH_TS_LTZ )) // out of order API expression
109+ .columnByExpression ("ts1" , callSql (COMPUTED_SQL_WITH_TS_LTZ ))
107110 .columnByMetadata ("ts_ltz" , DataTypes .TIMESTAMP_LTZ (3 ), "timestamp" )
108111 .watermark ("ts1" , WATERMARK_SQL_WITH_TS_LTZ )
109- .columnByExpression ("proctime" , PROCTIME_SQL )
110112 .build ();
111113
112114 @ Test
@@ -152,38 +154,53 @@ public void testSchemaResolutionWithTimestampLtzRowtime() {
152154 new ResolvedSchema (
153155 Arrays .asList (
154156 Column .physical ("id" , DataTypes .INT ().notNull ()),
155- Column .physical ("counter" , DataTypes .INT ().notNull ()),
156- Column .physical (
157- "payload" ,
158- DataTypes .ROW (
159- DataTypes .FIELD ("name" , DataTypes .STRING ()),
160- DataTypes .FIELD ("age" , DataTypes .INT ()),
161- DataTypes .FIELD ("flag" , DataTypes .BOOLEAN ()))),
162- Column .metadata ("topic" , DataTypes .STRING (), null , true ),
163157 Column .computed ("ts1" , COMPUTED_COLUMN_RESOLVED_WITH_TS_LTZ ),
164158 Column .metadata (
165- "ts_ltz" , DataTypes .TIMESTAMP_LTZ (3 ), "timestamp" , false ),
166- Column .computed ("proctime" , PROCTIME_RESOLVED )),
159+ "ts_ltz" , DataTypes .TIMESTAMP_LTZ (3 ), "timestamp" , false )),
167160 Collections .singletonList (
168161 WatermarkSpec .of ("ts1" , WATERMARK_RESOLVED_WITH_TS_LTZ )),
169- UniqueConstraint .primaryKey (
170- "primary_constraint" , Collections .singletonList ("id" )));
162+ null );
171163
172164 final ResolvedSchema actualStreamSchema = resolveSchema (SCHEMA_WITH_TS_LTZ , true );
173165 {
174166 assertThat (actualStreamSchema , equalTo (expectedSchema ));
175167 assertTrue (isRowtimeAttribute (getType (actualStreamSchema , "ts1" )));
176- assertTrue (isProctimeAttribute (getType (actualStreamSchema , "proctime" )));
177168 }
178169
179170 final ResolvedSchema actualBatchSchema = resolveSchema (SCHEMA_WITH_TS_LTZ , false );
180171 {
181172 assertThat (actualBatchSchema , equalTo (expectedSchema ));
182173 assertFalse (isRowtimeAttribute (getType (actualBatchSchema , "ts1" )));
183- assertTrue (isProctimeAttribute (getType (actualBatchSchema , "proctime" )));
184174 }
185175 }
186176
177+ @ Test
178+ public void testSchemaResolutionWithSourceWatermark () {
179+ final ResolvedSchema expectedSchema =
180+ new ResolvedSchema (
181+ Collections .singletonList (
182+ Column .physical ("ts_ltz" , DataTypes .TIMESTAMP_LTZ (1 ))),
183+ Collections .singletonList (
184+ WatermarkSpec .of (
185+ "ts_ltz" ,
186+ new CallExpression (
187+ FunctionIdentifier .of (
188+ BuiltInFunctionDefinitions .SOURCE_WATERMARK
189+ .getName ()),
190+ BuiltInFunctionDefinitions .SOURCE_WATERMARK ,
191+ Collections .emptyList (),
192+ DataTypes .TIMESTAMP_LTZ (1 )))),
193+ null );
194+ final ResolvedSchema resolvedSchema =
195+ resolveSchema (
196+ Schema .newBuilder ()
197+ .column ("ts_ltz" , DataTypes .TIMESTAMP_LTZ (1 ))
198+ .watermark ("ts_ltz" , sourceWatermark ())
199+ .build ());
200+
201+ assertThat (resolvedSchema , equalTo (expectedSchema ));
202+ }
203+
187204 @ Test
188205 public void testSchemaResolutionErrors () {
189206
@@ -282,20 +299,6 @@ public void testUnresolvedSchemaString() {
282299 + " WATERMARK FOR `ts` AS [ts - INTERVAL '5' SECOND],\n "
283300 + " CONSTRAINT `primary_constraint` PRIMARY KEY (`id`) NOT ENFORCED\n "
284301 + ")" ));
285- assertThat (
286- SCHEMA_WITH_TS_LTZ .toString (),
287- equalTo (
288- "(\n "
289- + " `id` INT NOT NULL,\n "
290- + " `counter` INT NOT NULL,\n "
291- + " `payload` [ROW<name STRING, age INT, flag BOOLEAN>],\n "
292- + " `topic` METADATA VIRTUAL,\n "
293- + " `ts1` AS [ts_ltz - INTERVAL '60' MINUTE],\n "
294- + " `ts_ltz` METADATA FROM 'timestamp',\n "
295- + " `proctime` AS [PROCTIME()],\n "
296- + " WATERMARK FOR `ts1` AS [ts1 - INTERVAL '5' SECOND],\n "
297- + " CONSTRAINT `primary_constraint` PRIMARY KEY (`id`) NOT ENFORCED\n "
298- + ")" ));
299302 }
300303
301304 @ Test
@@ -315,22 +318,6 @@ public void testResolvedSchemaString() {
315318 + " WATERMARK FOR `ts`: TIMESTAMP(3) AS ts - INTERVAL '5' SECOND,\n "
316319 + " CONSTRAINT `primary_constraint` PRIMARY KEY (`id`) NOT ENFORCED\n "
317320 + ")" ));
318-
319- final ResolvedSchema resolvedSchemaWithTsLtz = resolveSchema (SCHEMA_WITH_TS_LTZ );
320- assertThat (
321- resolvedSchemaWithTsLtz .toString (),
322- equalTo (
323- "(\n "
324- + " `id` INT NOT NULL,\n "
325- + " `counter` INT NOT NULL,\n "
326- + " `payload` ROW<`name` STRING, `age` INT, `flag` BOOLEAN>,\n "
327- + " `topic` STRING METADATA VIRTUAL,\n "
328- + " `ts1` TIMESTAMP_LTZ(3) *ROWTIME* AS ts_ltz - INTERVAL '60' MINUTE,\n "
329- + " `ts_ltz` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp',\n "
330- + " `proctime` TIMESTAMP_LTZ(3) NOT NULL *PROCTIME* AS PROCTIME(),\n "
331- + " WATERMARK FOR `ts1`: TIMESTAMP_LTZ(3) AS ts1 - INTERVAL '5' SECOND,\n "
332- + " CONSTRAINT `primary_constraint` PRIMARY KEY (`id`) NOT ENFORCED\n "
333- + ")" ));
334321 }
335322
336323 @ Test
0 commit comments