diff --git parser/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g parser/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g index c9da7a2..67ff8cf 100644 --- parser/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g +++ parser/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g @@ -174,6 +174,7 @@ KW_ENABLE: 'ENABLE' | 'ENABLED'; KW_DISABLE: 'DISABLE' | 'DISABLED'; KW_EXECUTED: 'EXECUTED'; +KW_EXECUTE: 'EXECUTE'; KW_LOCATION: 'LOCATION'; KW_TABLESAMPLE: 'TABLESAMPLE'; KW_BUCKET: 'BUCKET'; diff --git parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g index dbafa30..425beba 100644 --- parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g +++ parser/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g @@ -455,6 +455,7 @@ TOK_WITHIN_GROUP; TOK_CRON; TOK_EXECUTED_AS; +TOK_EXECUTE; } @@ -2126,6 +2127,7 @@ | executedAsSpec | enableSpecification | definedAsSpec + | KW_EXECUTE -> ^(TOK_EXECUTE) ; scheduleSpec diff --git parser/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g parser/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g index e6ea41a..aea49ce 100644 --- parser/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g +++ parser/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g @@ -865,7 +865,7 @@ | KW_TIMESTAMPTZ | KW_DEFAULT | KW_REOPTIMIZATION - | KW_EXECUTED | KW_SCHEDULED | KW_CRON + | KW_EXECUTED | KW_SCHEDULED | KW_CRON | KW_EXECUTE | KW_RESOURCE | KW_PLAN | KW_PLANS | KW_QUERY_PARALLELISM | KW_ACTIVATE | KW_MOVE | KW_DO | KW_POOL | KW_ALLOC_FRACTION | KW_SCHEDULING_POLICY | KW_PATH | KW_MAPPING | KW_WORKLOAD | KW_MANAGEMENT | KW_ACTIVE | KW_UNMANAGED | KW_UNKNOWN diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/ScheduledQueryAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/ScheduledQueryAnalyzer.java index 66394a3..83f00ae 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/ScheduledQueryAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/ScheduledQueryAnalyzer.java @@ -77,6 +77,8 @@ // in case the user will change; we have to run an authorization check beforehand checkAuthorization(type, schqStored); } + // clear the next execution time + schqStored.setNextExecutionIsSet(false); return composeOverlayObject(schqChanges, schqStored); } catch (TException e) { throw new SemanticException("unable to get Scheduled query" + e); @@ -169,6 +171,10 @@ case HiveParser.TOK_QUERY: schq.setQuery(unparseTree(node.getChild(0))); return; + case HiveParser.TOK_EXECUTE: + int now = (int) (System.currentTimeMillis() / 1000); + schq.setNextExecution(now); + return; default: throw new SemanticException("Unexpected token: " + node.getType()); } diff --git ql/src/test/org/apache/hadoop/hive/ql/schq/TestScheduledQueryStatements.java ql/src/test/org/apache/hadoop/hive/ql/schq/TestScheduledQueryStatements.java index ac4e164..e1d411f 100644 --- ql/src/test/org/apache/hadoop/hive/ql/schq/TestScheduledQueryStatements.java +++ ql/src/test/org/apache/hadoop/hive/ql/schq/TestScheduledQueryStatements.java @@ -18,6 +18,7 @@ package org.apache.hadoop.hive.ql.schq; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import org.apache.hadoop.hive.conf.HiveConf; @@ -32,6 +33,7 @@ import org.apache.hadoop.hive.ql.scheduled.ScheduledQueryExecutionService; import org.apache.hadoop.hive.ql.session.SessionState; import org.apache.hive.testutils.HiveTestEnvSetup; +import org.hamcrest.Matchers; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; @@ -136,7 +138,7 @@ IDriver driver = createDriver(); driver.run("set role admin"); - driver.run("create scheduled query alter1 cron '* * * * * ? *' as select 1 from tu"); + driver.run("create scheduled query alter1 cron '0 0 7 * * ? *' as select 1 from tu"); driver.run("alter scheduled query alter1 executed as 'user3'"); driver.run("alter scheduled query alter1 defined as select 22 from tu"); @@ -144,11 +146,27 @@ Optional sq = os.getMScheduledQuery(new ScheduledQueryKey("alter1", "hive")); assertTrue(sq.isPresent()); assertEquals("user3", sq.get().toThrift().getUser()); + assertThat(sq.get().getNextExecution(), Matchers.greaterThan((int) (System.currentTimeMillis() / 1000))); } } @Test + public void testExecuteImmediate() throws ParseException, Exception { + IDriver driver = createDriver(); + + driver.run("set role admin"); + driver.run("create scheduled query immed cron '0 0 7 * * ? *' as select 1"); + driver.run("alter scheduled query immed execute"); + + try (CloseableObjectStore os = new CloseableObjectStore(env_setup.getTestCtx().hiveConf)) { + Optional sq = os.getMScheduledQuery(new ScheduledQueryKey("immed", "hive")); + assertTrue(sq.isPresent()); + assertThat(sq.get().getNextExecution(), Matchers.lessThanOrEqualTo((int) (System.currentTimeMillis() / 1000))); + } + } + + @Test public void testImpersonation() throws ParseException, Exception { HiveConf conf = env_setup.getTestCtx().hiveConf; IDriver driver = createDriver(); diff --git standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java index 80d2111..bc03a5c 100644 --- standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java +++ standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java @@ -12852,11 +12852,15 @@ openTransaction(); MScheduledQuery persisted = existing.get(); persisted.doUpdate(schq); - Integer nextExecutionTime = computeNextExecutionTime(schq.getSchedule()); - if (nextExecutionTime == null) { - throw new InvalidInputException("Invalid schedule: " + schq.getSchedule()); + if (!scheduledQuery.isSetNextExecution()) { + Integer nextExecutionTime = computeNextExecutionTime(schq.getSchedule()); + if (nextExecutionTime == null) { + throw new InvalidInputException("Invalid schedule: " + schq.getSchedule()); + } + persisted.setNextExecution(nextExecutionTime); + } else { + persisted.setNextExecution(schq.getNextExecution()); } - persisted.setNextExecution(nextExecutionTime); pm.makePersistent(persisted); commited = commitTransaction(); } finally {