This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 8459091d167 Support parsing Doris CREATE JOB syntax (#38268)
8459091d167 is described below
commit 8459091d1674254a5c0cbb1fd83e3ed00ad195e2
Author: cxy <[email protected]>
AuthorDate: Sat Feb 28 17:13:51 2026 +0800
Support parsing Doris CREATE JOB syntax (#38268)
---
.../core/database/visitor/SQLVisitorRule.java | 2 +
.../src/main/antlr4/imports/doris/DDLStatement.g4 | 9 ++
.../sql/parser/autogen/DorisStatement.g4 | 1 +
.../statement/type/DorisDDLStatementVisitor.java | 41 +++++++
.../core/segment/ddl/job/JobCommentSegment.java | 36 ++++++
.../ddl/job/JobScheduleIntervalSegment.java | 38 ++++++
.../core/segment/ddl/job/JobScheduleSegment.java | 84 ++++++++++++++
.../ddl/job/JobScheduleTimestampSegment.java | 36 ++++++
.../doris/ddl/DorisCreateJobStatement.java | 58 ++++++++++
.../doris/DorisCreateJobStatementAssert.java | 121 +++++++++++++++++++
.../ddl/dialect/doris/DorisDDLStatementAssert.java | 4 +
.../cases/parser/jaxb/RootSQLParserTestCases.java | 4 +
.../jaxb/segment/impl/job/ExpectedJobComment.java | 38 ++++++
.../jaxb/segment/impl/job/ExpectedJobName.java | 30 +++++
.../jaxb/segment/impl/job/ExpectedJobSchedule.java | 51 ++++++++
.../impl/job/ExpectedJobScheduleInterval.java | 41 +++++++
.../impl/job/ExpectedJobScheduleTimestamp.java | 38 ++++++
.../doris/DorisCreateJobStatementTestCase.java | 58 ++++++++++
.../src/main/resources/case/ddl/create-job.xml | 128 +++++++++++++++++++++
.../resources/sql/supported/ddl/create-job.xml | 25 ++++
20 files changed, 843 insertions(+)
diff --git
a/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
b/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
index 8fa65d270ec..7bb6b8c6d69 100644
---
a/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
+++
b/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
@@ -289,6 +289,8 @@ public enum SQLVisitorRule {
UNLISTEN("Unlisten", SQLStatementType.DDL),
+ CREATE_JOB("CreateJob", SQLStatementType.DDL),
+
RESUME_JOB("ResumeJob", SQLStatementType.DDL),
RESUME_SYNC_JOB("ResumeSyncJob", SQLStatementType.DDL),
diff --git
a/parser/sql/engine/dialect/doris/src/main/antlr4/imports/doris/DDLStatement.g4
b/parser/sql/engine/dialect/doris/src/main/antlr4/imports/doris/DDLStatement.g4
index 1086a85f994..7752d04a71e 100644
---
a/parser/sql/engine/dialect/doris/src/main/antlr4/imports/doris/DDLStatement.g4
+++
b/parser/sql/engine/dialect/doris/src/main/antlr4/imports/doris/DDLStatement.g4
@@ -990,6 +990,15 @@ signalInformationItem
: conditionInformationItemName EQ_ expr
;
+createJob
+ : CREATE JOB jobName ON SCHEDULE jobScheduleExpression (COMMENT string_)?
DO insert
+ ;
+
+jobScheduleExpression
+ : AT timestampValue
+ | EVERY intervalValue (STARTS timestampValue)? (ENDS timestampValue)?
+ ;
+
resumeJob
: RESUME JOB WHERE jobName EQ_ stringLiterals
;
diff --git
a/parser/sql/engine/dialect/doris/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/DorisStatement.g4
b/parser/sql/engine/dialect/doris/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/DorisStatement.g4
index 96d91657da2..ab4336d5978 100644
---
a/parser/sql/engine/dialect/doris/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/DorisStatement.g4
+++
b/parser/sql/engine/dialect/doris/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/DorisStatement.g4
@@ -158,6 +158,7 @@ execute
| dropFile
| sync
| unsetVariable
+ | createJob
// TODO consider refactor following sytax to SEMI_? EOF
) (SEMI_ EOF? | EOF)
| EOF
diff --git
a/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
b/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
index 1ff0587bac8..d98a6f1f00c 100644
---
a/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
+++
b/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
@@ -67,6 +67,8 @@ import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.Compoun
import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateDatabaseContext;
import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateDefinitionClauseContext;
import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateEventContext;
+import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateJobContext;
+import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.JobScheduleExpressionContext;
import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateFunctionContext;
import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateIndexContext;
import
org.apache.shardingsphere.sql.parser.autogen.DorisStatementParser.CreateLikeClauseContext;
@@ -188,7 +190,11 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.rollup.Ro
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.FunctionNameSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.RoutineBodySegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.ValidStatementSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobCommentSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobNameSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobScheduleIntervalSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobScheduleSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobScheduleTimestampSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.ChannelDescriptionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.BinlogDescriptionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.table.AlgorithmTypeSegment;
@@ -259,6 +265,7 @@ import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisResumeJobSt
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisResumeSyncJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisPauseSyncJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisCreateSyncJobStatement;
+import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisCreateJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisStopSyncJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.event.MySQLAlterEventStatement;
import
org.apache.shardingsphere.sql.parser.statement.mysql.ddl.event.MySQLCreateEventStatement;
@@ -469,6 +476,40 @@ public final class DorisDDLStatementVisitor extends
DorisStatementVisitor implem
return new PropertySegment(ctx.start.getStartIndex(),
ctx.stop.getStopIndex(), key, value);
}
+ @Override
+ public ASTNode visitCreateJob(final CreateJobContext ctx) {
+ DorisCreateJobStatement result = new
DorisCreateJobStatement(getDatabaseType());
+ result.setJobName(new
JobNameSegment(ctx.jobName().start.getStartIndex(),
ctx.jobName().stop.getStopIndex(), (IdentifierValue)
visit(ctx.jobName().identifier())));
+
result.setSchedule(createJobScheduleSegment(ctx.jobScheduleExpression()));
+ if (null != ctx.COMMENT() && null != ctx.string_()) {
+ result.setComment(new
JobCommentSegment(ctx.COMMENT().getSymbol().getStartIndex(),
ctx.string_().stop.getStopIndex(),
SQLUtils.getExactlyValue(ctx.string_().getText())));
+ }
+ result.setInsertStatement((InsertStatement) visit(ctx.insert()));
+ return result;
+ }
+
+ private JobScheduleSegment createJobScheduleSegment(final
JobScheduleExpressionContext ctx) {
+ boolean everySchedule = null == ctx.AT();
+ JobScheduleSegment result = new
JobScheduleSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(),
everySchedule);
+ if (!everySchedule) {
+ result.setAtTimestamp(
+ new
JobScheduleTimestampSegment(ctx.timestampValue(0).start.getStartIndex(),
ctx.timestampValue(0).stop.getStopIndex(),
SQLUtils.getExactlyValue(ctx.timestampValue(0).getText())));
+ } else {
+ result.setInterval(new
JobScheduleIntervalSegment(ctx.intervalValue().start.getStartIndex(),
ctx.intervalValue().stop.getStopIndex(),
Long.parseLong(ctx.intervalValue().expr().getText()),
+ ctx.intervalValue().intervalUnit().getText()));
+ if (null != ctx.STARTS()) {
+ result.setStartsTimestamp(new
JobScheduleTimestampSegment(ctx.timestampValue(0).start.getStartIndex(),
ctx.timestampValue(0).stop.getStopIndex(),
+
SQLUtils.getExactlyValue(ctx.timestampValue(0).getText())));
+ }
+ if (null != ctx.ENDS()) {
+ int endsTimestampIndex = null != ctx.STARTS() ? 1 : 0;
+ result.setEndsTimestamp(new
JobScheduleTimestampSegment(ctx.timestampValue(endsTimestampIndex).start.getStartIndex(),
ctx.timestampValue(endsTimestampIndex).stop.getStopIndex(),
+
SQLUtils.getExactlyValue(ctx.timestampValue(endsTimestampIndex).getText())));
+ }
+ }
+ return result;
+ }
+
@SuppressWarnings("unchecked")
@Override
public ASTNode visitCreateTable(final CreateTableContext ctx) {
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobCommentSegment.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobCommentSegment.java
new file mode 100644
index 00000000000..8e360638e3b
--- /dev/null
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobCommentSegment.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
+
+/**
+ * Job comment segment.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class JobCommentSegment implements SQLSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final String value;
+}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleIntervalSegment.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleIntervalSegment.java
new file mode 100644
index 00000000000..3e9a71d72b2
--- /dev/null
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleIntervalSegment.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
+
+/**
+ * Job schedule interval segment.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class JobScheduleIntervalSegment implements SQLSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final long value;
+
+ private final String unit;
+}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleSegment.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleSegment.java
new file mode 100644
index 00000000000..d04dd1d726f
--- /dev/null
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleSegment.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
+
+import java.util.Optional;
+
+/**
+ * Job schedule segment.
+ */
+@RequiredArgsConstructor
+@Getter
+@Setter
+public final class JobScheduleSegment implements SQLSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final boolean everySchedule;
+
+ private JobScheduleTimestampSegment atTimestamp;
+
+ private JobScheduleIntervalSegment interval;
+
+ private JobScheduleTimestampSegment startsTimestamp;
+
+ private JobScheduleTimestampSegment endsTimestamp;
+
+ /**
+ * Get at timestamp segment.
+ *
+ * @return at timestamp segment
+ */
+ public Optional<JobScheduleTimestampSegment> getAtTimestamp() {
+ return Optional.ofNullable(atTimestamp);
+ }
+
+ /**
+ * Get interval segment.
+ *
+ * @return interval segment
+ */
+ public Optional<JobScheduleIntervalSegment> getInterval() {
+ return Optional.ofNullable(interval);
+ }
+
+ /**
+ * Get starts timestamp segment.
+ *
+ * @return starts timestamp segment
+ */
+ public Optional<JobScheduleTimestampSegment> getStartsTimestamp() {
+ return Optional.ofNullable(startsTimestamp);
+ }
+
+ /**
+ * Get ends timestamp segment.
+ *
+ * @return ends timestamp segment
+ */
+ public Optional<JobScheduleTimestampSegment> getEndsTimestamp() {
+ return Optional.ofNullable(endsTimestamp);
+ }
+}
diff --git
a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleTimestampSegment.java
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleTimestampSegment.java
new file mode 100644
index 00000000000..f6e761d532a
--- /dev/null
+++
b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/segment/ddl/job/JobScheduleTimestampSegment.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.SQLSegment;
+
+/**
+ * Job schedule timestamp segment.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class JobScheduleTimestampSegment implements SQLSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final String value;
+}
diff --git
a/parser/sql/statement/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateJobStatement.java
b/parser/sql/statement/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateJobStatement.java
new file mode 100644
index 00000000000..13c1c601f48
--- /dev/null
+++
b/parser/sql/statement/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/statement/doris/ddl/DorisCreateJobStatement.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.statement.doris.ddl;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobCommentSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobNameSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobScheduleSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.DDLStatement;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
+
+import java.util.Optional;
+
+/**
+ * Create job statement for Doris.
+ */
+@Getter
+@Setter
+public final class DorisCreateJobStatement extends DDLStatement {
+
+ private JobNameSegment jobName;
+
+ private JobScheduleSegment schedule;
+
+ private JobCommentSegment comment;
+
+ private InsertStatement insertStatement;
+
+ public DorisCreateJobStatement(final DatabaseType databaseType) {
+ super(databaseType);
+ }
+
+ /**
+ * Get comment.
+ *
+ * @return comment
+ */
+ public Optional<JobCommentSegment> getComment() {
+ return Optional.ofNullable(comment);
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisCreateJobStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisCreateJobStatementAssert.java
new file mode 100644
index 00000000000..aa2aad2dbe1
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisCreateJobStatementAssert.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.doris;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobCommentSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.job.JobScheduleSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisCreateJobStatement;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.SQLSegmentAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.table.TableAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.where.WhereClauseAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job.ExpectedJobSchedule;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisCreateJobStatementTestCase;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Create job statement assert for Doris.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class DorisCreateJobStatementAssert {
+
+ /**
+ * Assert create job statement is correct with expected parser result.
+ *
+ * @param assertContext assert context
+ * @param actual actual create job statement
+ * @param expected expected create job statement test case
+ */
+ public static void assertIs(final SQLCaseAssertContext assertContext,
final DorisCreateJobStatement actual, final DorisCreateJobStatementTestCase
expected) {
+ assertJobName(assertContext, actual, expected);
+ assertSchedule(assertContext, actual, expected);
+ assertComment(assertContext, actual, expected);
+ assertInsertStatement(assertContext, actual, expected);
+ }
+
+ private static void assertJobName(final SQLCaseAssertContext
assertContext, final DorisCreateJobStatement actual, final
DorisCreateJobStatementTestCase expected) {
+ assertNotNull(actual.getJobName(), assertContext.getText("Job name
should exist."));
+ assertThat(assertContext.getText("Job name does not match: "),
actual.getJobName().getIdentifier().getValue(),
is(expected.getJobName().getName()));
+ SQLSegmentAssert.assertIs(assertContext, actual.getJobName(),
expected.getJobName());
+ }
+
+ private static void assertSchedule(final SQLCaseAssertContext
assertContext, final DorisCreateJobStatement actual, final
DorisCreateJobStatementTestCase expected) {
+ assertNotNull(actual.getSchedule(), assertContext.getText("Schedule
should exist."));
+ assertNotNull(expected.getSchedule(), assertContext.getText("Expected
schedule should exist."));
+ JobScheduleSegment actualSchedule = actual.getSchedule();
+ ExpectedJobSchedule expectedSchedule = expected.getSchedule();
+ SQLSegmentAssert.assertIs(assertContext, actualSchedule,
expectedSchedule);
+ assertThat(assertContext.getText("Every schedule flag does not match:
"), actualSchedule.isEverySchedule(), is(expectedSchedule.isEverySchedule()));
+ if (null != expectedSchedule.getAtTimestamp()) {
+ assertTrue(actualSchedule.getAtTimestamp().isPresent(),
assertContext.getText("At timestamp should exist."));
+ assertThat(assertContext.getText("At timestamp value does not
match: "), actualSchedule.getAtTimestamp().get().getValue(),
is(expectedSchedule.getAtTimestamp().getValue()));
+ SQLSegmentAssert.assertIs(assertContext,
actualSchedule.getAtTimestamp().get(), expectedSchedule.getAtTimestamp());
+ }
+ if (null != expectedSchedule.getInterval()) {
+ assertTrue(actualSchedule.getInterval().isPresent(),
assertContext.getText("Interval should exist."));
+ assertThat(assertContext.getText("Interval value does not match:
"), actualSchedule.getInterval().get().getValue(),
is(expectedSchedule.getInterval().getValue()));
+ assertThat(assertContext.getText("Interval unit does not match:
"), actualSchedule.getInterval().get().getUnit(),
is(expectedSchedule.getInterval().getUnit()));
+ SQLSegmentAssert.assertIs(assertContext,
actualSchedule.getInterval().get(), expectedSchedule.getInterval());
+ }
+ if (null != expectedSchedule.getStartsTimestamp()) {
+ assertTrue(actualSchedule.getStartsTimestamp().isPresent(),
assertContext.getText("Starts timestamp should exist."));
+ assertThat(assertContext.getText("Starts timestamp value does not
match: "), actualSchedule.getStartsTimestamp().get().getValue(),
is(expectedSchedule.getStartsTimestamp().getValue()));
+ SQLSegmentAssert.assertIs(assertContext,
actualSchedule.getStartsTimestamp().get(),
expectedSchedule.getStartsTimestamp());
+ }
+ if (null != expectedSchedule.getEndsTimestamp()) {
+ assertTrue(actualSchedule.getEndsTimestamp().isPresent(),
assertContext.getText("Ends timestamp should exist."));
+ assertThat(assertContext.getText("Ends timestamp value does not
match: "), actualSchedule.getEndsTimestamp().get().getValue(),
is(expectedSchedule.getEndsTimestamp().getValue()));
+ SQLSegmentAssert.assertIs(assertContext,
actualSchedule.getEndsTimestamp().get(), expectedSchedule.getEndsTimestamp());
+ }
+ }
+
+ private static void assertComment(final SQLCaseAssertContext
assertContext, final DorisCreateJobStatement actual, final
DorisCreateJobStatementTestCase expected) {
+ if (null != expected.getComment()) {
+ assertTrue(actual.getComment().isPresent(),
assertContext.getText("Comment should exist."));
+ JobCommentSegment actualComment = actual.getComment().get();
+ assertThat(assertContext.getText("Comment value does not match:
"), actualComment.getValue(), is(expected.getComment().getValue()));
+ SQLSegmentAssert.assertIs(assertContext, actualComment,
expected.getComment());
+ }
+ }
+
+ private static void assertInsertStatement(final SQLCaseAssertContext
assertContext, final DorisCreateJobStatement actual, final
DorisCreateJobStatementTestCase expected) {
+ assertNotNull(actual.getInsertStatement(),
assertContext.getText("Insert statement should exist."));
+ if (null != expected.getInsertTable()) {
+ assertTrue(actual.getInsertStatement().getTable().isPresent(),
assertContext.getText("Insert target table should exist."));
+ TableAssert.assertIs(assertContext,
actual.getInsertStatement().getTable().get(), expected.getInsertTable());
+ }
+ if (null != expected.getInsertSelectTable()) {
+
assertTrue(actual.getInsertStatement().getInsertSelect().isPresent(),
assertContext.getText("Insert select should exist."));
+ SimpleTableSegment fromTable = (SimpleTableSegment)
actual.getInsertStatement().getInsertSelect().get().getSelect().getFrom().orElse(null);
+ assertNotNull(fromTable, assertContext.getText("Insert select from
table should exist."));
+ TableAssert.assertIs(assertContext, fromTable,
expected.getInsertSelectTable());
+ }
+ if (null != expected.getInsertSelectWhere()) {
+
assertTrue(actual.getInsertStatement().getInsertSelect().isPresent(),
assertContext.getText("Insert select should exist."));
+
assertTrue(actual.getInsertStatement().getInsertSelect().get().getSelect().getWhere().isPresent(),
assertContext.getText("Insert select where should exist."));
+ WhereClauseAssert.assertIs(assertContext,
actual.getInsertStatement().getInsertSelect().get().getSelect().getWhere().get(),
expected.getInsertSelectWhere());
+ }
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisDDLStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisDDLStatementAssert.java
index 1cc91c5a069..8c39f0e303a 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisDDLStatementAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/doris/DorisDDLStatementAssert.java
@@ -27,11 +27,13 @@ import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisResumeJobSt
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisResumeSyncJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisPauseSyncJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisStopSyncJobStatement;
+import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisCreateJobStatement;
import
org.apache.shardingsphere.sql.parser.statement.doris.ddl.DorisCreateSyncJobStatement;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.doris.type.DorisAlterStoragePolicyStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.SQLParserTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisAlterStoragePolicyStatementTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisCreateJobStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisDropFunctionStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisResumeJobStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisResumeSyncJobStatementTestCase;
@@ -70,6 +72,8 @@ public final class DorisDDLStatementAssert {
DorisCreateSyncJobStatementAssert.assertIs(assertContext,
(DorisCreateSyncJobStatement) actual, (DorisCreateSyncJobStatementTestCase)
expected);
} else if (actual instanceof DorisStopSyncJobStatement) {
DorisStopSyncJobStatementAssert.assertIs(assertContext,
(DorisStopSyncJobStatement) actual, (DorisStopSyncJobStatementTestCase)
expected);
+ } else if (actual instanceof DorisCreateJobStatement) {
+ DorisCreateJobStatementAssert.assertIs(assertContext,
(DorisCreateJobStatement) actual, (DorisCreateJobStatementTestCase) expected);
}
}
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
index 0d7165aaec1..2747495c648 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
@@ -33,6 +33,7 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.s
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisResumeSyncJobStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisPauseSyncJobStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisStopSyncJobStatementTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisCreateJobStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris.DorisCreateSyncJobStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.dal.dialect.doris.DorisAlterSqlBlockRuleStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.dal.dialect.doris.DorisDropSqlBlockRuleStatementTestCase;
@@ -566,6 +567,9 @@ public final class RootSQLParserTestCases {
@XmlElement(name = "create-sync-job")
private final List<DorisCreateSyncJobStatementTestCase>
createSyncJobTestCases = new LinkedList<>();
+ @XmlElement(name = "create-job")
+ private final List<DorisCreateJobStatementTestCase> createJobTestCases =
new LinkedList<>();
+
@XmlElement(name = "alter-catalog")
private final List<AlterCatalogStatementTestCase> alterCatalogTestCases =
new LinkedList<>();
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobComment.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobComment.java
new file mode 100644
index 00000000000..53a8179a0de
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobComment.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Expected job comment.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@Getter
+@Setter
+public final class ExpectedJobComment extends AbstractExpectedSQLSegment {
+
+ @XmlAttribute
+ private String value;
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobName.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobName.java
new file mode 100644
index 00000000000..c6f107886aa
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobName.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedIdentifierSQLSegment;
+
+/**
+ * Expected job name.
+ */
+@Getter
+@Setter
+public final class ExpectedJobName extends
AbstractExpectedIdentifierSQLSegment {
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobSchedule.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobSchedule.java
new file mode 100644
index 00000000000..efbf7f05b5e
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobSchedule.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Expected job schedule segment.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@Getter
+@Setter
+public final class ExpectedJobSchedule extends AbstractExpectedSQLSegment {
+
+ @XmlAttribute(name = "every-schedule")
+ private boolean everySchedule;
+
+ @XmlElement(name = "at-timestamp")
+ private ExpectedJobScheduleTimestamp atTimestamp;
+
+ @XmlElement(name = "interval")
+ private ExpectedJobScheduleInterval interval;
+
+ @XmlElement(name = "starts-timestamp")
+ private ExpectedJobScheduleTimestamp startsTimestamp;
+
+ @XmlElement(name = "ends-timestamp")
+ private ExpectedJobScheduleTimestamp endsTimestamp;
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobScheduleInterval.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobScheduleInterval.java
new file mode 100644
index 00000000000..6bb2fa0dc33
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobScheduleInterval.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Expected job schedule interval.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@Getter
+@Setter
+public final class ExpectedJobScheduleInterval extends
AbstractExpectedSQLSegment {
+
+ @XmlAttribute
+ private long value;
+
+ @XmlAttribute
+ private String unit;
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobScheduleTimestamp.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobScheduleTimestamp.java
new file mode 100644
index 00000000000..1d910480067
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/job/ExpectedJobScheduleTimestamp.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedSQLSegment;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+/**
+ * Expected job schedule timestamp.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@Getter
+@Setter
+public final class ExpectedJobScheduleTimestamp extends
AbstractExpectedSQLSegment {
+
+ @XmlAttribute
+ private String value;
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/dialect/doris/DorisCreateJobStatementTestCase.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/dialect/doris/DorisCreateJobStatementTestCase.java
new file mode 100644
index 00000000000..a286b8b106e
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/dialect/doris/DorisCreateJobStatementTestCase.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.doris;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.SQLParserTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job.ExpectedJobComment;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job.ExpectedJobName;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.job.ExpectedJobSchedule;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedSimpleTable;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.where.ExpectedWhereClause;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Create job statement test case for Doris.
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@Getter
+@Setter
+public final class DorisCreateJobStatementTestCase extends SQLParserTestCase {
+
+ @XmlElement(name = "job-name")
+ private ExpectedJobName jobName;
+
+ @XmlElement(name = "schedule")
+ private ExpectedJobSchedule schedule;
+
+ @XmlElement(name = "job-comment")
+ private ExpectedJobComment comment;
+
+ @XmlElement(name = "insert-table")
+ private ExpectedSimpleTable insertTable;
+
+ @XmlElement(name = "insert-select-table")
+ private ExpectedSimpleTable insertSelectTable;
+
+ @XmlElement(name = "insert-select-where")
+ private ExpectedWhereClause insertSelectWhere;
+}
diff --git a/test/it/parser/src/main/resources/case/ddl/create-job.xml
b/test/it/parser/src/main/resources/case/ddl/create-job.xml
new file mode 100644
index 00000000000..860054f05c9
--- /dev/null
+++ b/test/it/parser/src/main/resources/case/ddl/create-job.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<sql-parser-test-cases>
+ <create-job sql-case-id="create_job_every_minute">
+ <job-name name="my_job" start-index="11" stop-index="16" />
+ <schedule start-index="30" stop-index="43" every-schedule="true">
+ <interval start-index="36" stop-index="43" value="1" unit="MINUTE"
/>
+ </schedule>
+ <insert-table name="tbl1" start-index="60" stop-index="67">
+ <owner name="db1" start-index="60" stop-index="62" />
+ </insert-table>
+ <insert-select-table name="tbl2" start-index="83" stop-index="90">
+ <owner name="db2" start-index="83" stop-index="85" />
+ </insert-select-table>
+ </create-job>
+
+ <create-job sql-case-id="create_job_at_once">
+ <job-name name="my_job" start-index="11" stop-index="16" />
+ <schedule start-index="30" stop-index="53" every-schedule="false">
+ <at-timestamp start-index="33" stop-index="53" value="2020-01-01
00:00:00" />
+ </schedule>
+ <insert-table name="tbl1" start-index="70" stop-index="77">
+ <owner name="db1" start-index="70" stop-index="72" />
+ </insert-table>
+ <insert-select-table name="tbl2" start-index="93" stop-index="100">
+ <owner name="db2" start-index="93" stop-index="95" />
+ </insert-select-table>
+ </create-job>
+
+ <create-job sql-case-id="create_job_every_day_with_starts">
+ <job-name name="my_job" start-index="11" stop-index="16" />
+ <schedule start-index="30" stop-index="69" every-schedule="true">
+ <interval start-index="36" stop-index="40" value="1" unit="DAY" />
+ <starts-timestamp start-index="49" stop-index="69"
value="2020-01-01 00:00:00" />
+ </schedule>
+ <insert-table name="tbl1" start-index="86" stop-index="93">
+ <owner name="db1" start-index="86" stop-index="88" />
+ </insert-table>
+ <insert-select-table name="tbl2" start-index="109" stop-index="116">
+ <owner name="db2" start-index="109" stop-index="111" />
+ </insert-select-table>
+ <insert-select-where start-index="118" stop-index="156">
+ <expr>
+ <binary-operation-expression start-index="124"
stop-index="156">
+ <left>
+ <column name="create_time" start-index="124"
stop-index="134" />
+ </left>
+ <operator>>=</operator>
+ <right>
+ <function function-name="days_add" start-index="139"
stop-index="156" text="days_add(now(),-1)">
+ <parameter>
+ <function function-name="now"
start-index="148" stop-index="152" text="now()" />
+ </parameter>
+ <parameter>
+ <literal-expression start-index="154"
stop-index="155" value="-1" />
+ </parameter>
+ </function>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </insert-select-where>
+ </create-job>
+
+ <create-job sql-case-id="create_job_every_day_with_starts_and_ends">
+ <job-name name="my_job" start-index="11" stop-index="16" />
+ <schedule start-index="30" stop-index="96" every-schedule="true">
+ <interval start-index="36" stop-index="40" value="1" unit="DAY" />
+ <starts-timestamp start-index="49" stop-index="69"
value="2020-01-01 00:00:00" />
+ <ends-timestamp start-index="76" stop-index="96" value="2020-01-01
00:10:00" />
+ </schedule>
+ <insert-table name="tbl1" start-index="113" stop-index="120">
+ <owner name="db1" start-index="113" stop-index="115" />
+ </insert-table>
+ <insert-select-table name="tbl2" start-index="136" stop-index="143">
+ <owner name="db2" start-index="136" stop-index="138" />
+ </insert-select-table>
+ <insert-select-where start-index="145" stop-index="183">
+ <expr>
+ <binary-operation-expression start-index="151"
stop-index="183">
+ <left>
+ <column name="create_time" start-index="151"
stop-index="161" />
+ </left>
+ <operator>>=</operator>
+ <right>
+ <function function-name="days_add" start-index="166"
stop-index="183" text="days_add(now(),-1)">
+ <parameter>
+ <function function-name="now"
start-index="175" stop-index="179" text="now()" />
+ </parameter>
+ <parameter>
+ <literal-expression start-index="181"
stop-index="182" value="-1" />
+ </parameter>
+ </function>
+ </right>
+ </binary-operation-expression>
+ </expr>
+ </insert-select-where>
+ </create-job>
+
+ <create-job sql-case-id="create_job_every_minute_with_comment">
+ <job-name name="my_job" start-index="11" stop-index="16" />
+ <schedule start-index="30" stop-index="43" every-schedule="true">
+ <interval start-index="36" stop-index="43" value="1" unit="MINUTE"
/>
+ </schedule>
+ <job-comment start-index="45" stop-index="66" value="test comment" />
+ <insert-table name="tbl1" start-index="83" stop-index="90">
+ <owner name="db1" start-index="83" stop-index="85" />
+ </insert-table>
+ <insert-select-table name="tbl2" start-index="106" stop-index="113">
+ <owner name="db2" start-index="106" stop-index="108" />
+ </insert-select-table>
+ </create-job>
+</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/ddl/create-job.xml
b/test/it/parser/src/main/resources/sql/supported/ddl/create-job.xml
new file mode 100644
index 00000000000..0af36dc8c41
--- /dev/null
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-job.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<sql-cases>
+ <sql-case id="create_job_every_minute" value="CREATE JOB my_job ON
SCHEDULE EVERY 1 MINUTE DO INSERT INTO db1.tbl1 SELECT * FROM db2.tbl2"
db-types="Doris" />
+ <sql-case id="create_job_at_once" value="CREATE JOB my_job ON SCHEDULE AT
'2020-01-01 00:00:00' DO INSERT INTO db1.tbl1 SELECT * FROM db2.tbl2"
db-types="Doris" />
+ <sql-case id="create_job_every_day_with_starts" value="CREATE JOB my_job
ON SCHEDULE EVERY 1 DAY STARTS '2020-01-01 00:00:00' DO INSERT INTO db1.tbl1
SELECT * FROM db2.tbl2 WHERE create_time >= days_add(now(),-1)"
db-types="Doris" />
+ <sql-case id="create_job_every_day_with_starts_and_ends" value="CREATE JOB
my_job ON SCHEDULE EVERY 1 DAY STARTS '2020-01-01 00:00:00' ENDS '2020-01-01
00:10:00' DO INSERT INTO db1.tbl1 SELECT * FROM db2.tbl2 WHERE create_time
>= days_add(now(),-1)" db-types="Doris" />
+ <sql-case id="create_job_every_minute_with_comment" value="CREATE JOB
my_job ON SCHEDULE EVERY 1 MINUTE COMMENT 'test comment' DO INSERT INTO
db1.tbl1 SELECT * FROM db2.tbl2" db-types="Doris" />
+</sql-cases>