>From Abhishek Jindal <[email protected]>:

Abhishek Jindal has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19369 )


Change subject: [WIP] [ASTERIXDB-3526] : SQL++ Update support #7
......................................................................

[WIP] [ASTERIXDB-3526] : SQL++ Update support #7

* Cleanup, add comments and address minor TODOs

Change-Id: I72b4d8fb6718cf5cf5431d755cd525fa546fd2be
---
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeToSetExpressionVisitor.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
M 
asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeSeqToSelectExprVisitor.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
M 
hyracks-fullstack/algebricks/algebricks-runtime/src/main/java/org/apache/hyracks/algebricks/runtime/operators/meta/SubplanRuntimeFactory.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
M 
asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
M 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/CheckIntegerDescriptor.java
10 files changed, 28 insertions(+), 114 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/69/19369/1

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index e9068c6..ad1aa7a 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -733,49 +733,43 @@
         return new Pair<>(finalAssignOp, resultVar);
     }

-    // TODO (abhij): Implement
+    /** Won't encounter these Update expressions here, as these have been 
rewritten beforehand */
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(SetElement setelem, 
Mutable<ILogicalOperator> tupSource)
             throws CompilationException {
         return new Pair<>(null, null);
     }

-    // TODO (abhij): Implement
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(SetExpression 
setexpr, Mutable<ILogicalOperator> tupSource)
             throws CompilationException {
         return new Pair<>(null, null);
     }

-    // TODO (abhij): Implement
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(UpdateExpression 
updateexpr,
             Mutable<ILogicalOperator> tupSource) throws CompilationException {
         return new Pair<>(null, null);
     }

-    // TODO (abhij): Implement
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(DeleteExpression 
deleteExpr,
             Mutable<ILogicalOperator> tupSource) throws CompilationException {
         return new Pair<>(null, null);
     }

-    // TODO (abhij): Implement
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(InsertExpression 
insertExpr,
             Mutable<ILogicalOperator> tupSource) throws CompilationException {
         return new Pair<>(null, null);
     }

-    // TODO (abhij): Implement
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(ChangeExpression 
changeExpr,
             Mutable<ILogicalOperator> tupSource) throws CompilationException {
         return new Pair<>(null, null);
     }

-    // TODO (abhij): Implement
     @Override
     public Pair<ILogicalOperator, LogicalVariable> visit(ChangeSeqExpression 
changeSeqExpr,
             Mutable<ILogicalOperator> tupSource) throws CompilationException {
diff --git 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 31f3b2a..4ed1a90 100644
--- 
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ 
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -509,14 +509,6 @@
                         handleInsertUpsertStatement(metadataProvider, stmt, 
hcc, resultSet, resultDelivery, outMetadata,
                                 stats, requestParameters, stmtParams, 
stmtRewriter);
                         break;
-                    /*case UPDATE:
-                        // TODO (abhij) : Introduce resultSet, resultDelivery, 
outMetadata
-                        // TODO (abhij) : Think about how to provide UPDATE 
stats
-                        if (stats.getProfileType() == Stats.ProfileType.FULL) {
-                            this.jobFlags.add(JobFlag.PROFILE_RUNTIME);
-                        }
-                        handleUpdateStatement(metadataProvider, stmt, hcc, 
stmtParams, stmtRewriter, requestParameters);
-                        break;*/
                     case DELETE:
                         handleDeleteStatement(metadataProvider, stmt, hcc, 
stmtParams, stmtRewriter, requestParameters);
                         break;
@@ -4305,80 +4297,6 @@
         return null;
     }

-    /*public JobSpecification handleUpdateStatement(MetadataProvider 
metadataProvider, Statement stmt,
-            IHyracksClientConnection hcc, Map<String, IAObject> stmtParams, 
IStatementRewriter stmtRewriter,
-            IRequestParameters requestParameters) throws Exception {
-        UpdateStatementV2 stmtUpdate = (UpdateStatementV2) stmt;
-        String datasetName = stmtUpdate.getDatasetName();
-        metadataProvider.validateDatabaseObjectName(stmtUpdate.getNamespace(), 
datasetName, stmt.getSourceLocation());
-        Namespace stmtActiveNamespace = 
getActiveNamespace(stmtUpdate.getNamespace());
-        DataverseName dataverseName = stmtActiveNamespace.getDataverseName();
-        String databaseName = stmtActiveNamespace.getDatabaseName();
-        MetadataTransactionContext mdTxnCtx = 
MetadataManager.INSTANCE.beginTransaction();
-        boolean bActiveTxn = true;
-        metadataProvider.setMetadataTxnContext(mdTxnCtx);
-        lockUtil.insertDeleteUpsertBegin(lockManager, 
metadataProvider.getLocks(), databaseName, dataverseName,
-                datasetName);
-        boolean atomic = false;
-        JobId jobId = null;
-        try {
-            metadataProvider.setWriteTransaction(true);
-            CompiledUpsertStatement clfrqs = new 
CompiledUpsertStatement(databaseName, dataverseName, datasetName,
-                    stmtUpdate.getQuery(), stmtUpdate.getVarCounter(), 
stmtUpdate.getAliasVar(), null);
-            clfrqs.setSourceLocation(stmt.getSourceLocation());
-            JobSpecification jobSpec =
-                    rewriteCompileQuery(hcc, metadataProvider, 
clfrqs.getQuery(), clfrqs, stmtParams, null);
-            appCtx.getReceptionist().ensureAuthorized(requestParameters, 
metadataProvider);
-            afterCompile();
-
-            MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
-            bActiveTxn = false;
-            if (jobSpec != null && !isCompileOnly()) {
-                Dataset ds = metadataProvider.findDataset(databaseName, 
dataverseName, datasetName);
-                atomic = ds.isAtomic();
-                if (atomic) {
-                    int numParticipatingNodes = appCtx.getNodeJobTracker()
-                            .getJobParticipatingNodes(jobSpec, 
LSMTreeIndexInsertUpdateDeleteOperatorDescriptor.class)
-                            .size();
-                    int numParticipatingPartitions = 
appCtx.getNodeJobTracker().getNumParticipatingPartitions(jobSpec,
-                            
LSMTreeIndexInsertUpdateDeleteOperatorDescriptor.class);
-                    List<Integer> participatingDatasetIds = new ArrayList<>();
-                    participatingDatasetIds.add(ds.getDatasetId());
-                    
jobSpec.setProperty(GlobalTxManager.GlOBAL_TX_PROPERTY_NAME, new GlobalTxInfo(
-                            participatingDatasetIds, numParticipatingNodes, 
numParticipatingPartitions));
-                }
-                String reqId = 
requestParameters.getRequestReference().getUuid();
-                final IRequestTracker requestTracker = 
appCtx.getRequestTracker();
-                final ClientRequest clientRequest = (ClientRequest) 
requestTracker.get(reqId);
-                jobId = runTrackJob(hcc, jobSpec, jobFlags, reqId, 
requestParameters.getClientContextId(),
-                        clientRequest);
-                clientRequest.markCancellable();
-                String nameBefore = Thread.currentThread().getName();
-                try {
-                    Thread.currentThread().setName(nameBefore + " : 
WaitForCompletionForJobId: " + jobId);
-                    hcc.waitForCompletion(jobId);
-                    ensureNotCancelled(clientRequest);
-                } finally {
-                    Thread.currentThread().setName(nameBefore);
-                }
-                if (atomic) {
-                    globalTxManager.commitTransaction(jobId);
-                }
-            }
-            return jobSpec;
-        } catch (Exception e) {
-            if (atomic && jobId != null) {
-                globalTxManager.abortTransaction(jobId);
-            }
-            if (bActiveTxn) {
-                abort(e, e, mdTxnCtx);
-            }
-            throw e;
-        } finally {
-            metadataProvider.getLocks().unlock();
-        }
-    }*/
-
     public JobSpecification handleDeleteStatement(MetadataProvider 
metadataProvider, Statement stmt,
             IHyracksClientConnection hcc, Map<String, IAObject> stmtParams, 
IStatementRewriter stmtRewriter,
             IRequestParameters requestParameters) throws Exception {
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index 82edf67..8be6a9e 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -105,7 +105,7 @@

 public class SqlppQueryRewriter implements IQueryRewriter {

-    private static final Logger LOGGER = 
LogManager.getLogger(SqlppQueryRewriter.class); // TODO (abhij): Revert to 
SqlppQueryRewriter.class
+    private static final Logger LOGGER = 
LogManager.getLogger(SqlppQueryRewriter.class);

     public static final String INLINE_WITH_OPTION = "inline_with";
     private static final boolean INLINE_WITH_OPTION_DEFAULT = true;
@@ -415,8 +415,7 @@

     private void logExpression(String p0, String p1) throws 
CompilationException {
         if (isLogEnabled) {
-            LOGGER.info("{} {}\n{}", p0, p1, 
LogRedactionUtil.userData(SqlppAstPrintUtil.toString(topStatement)));
-            // TODO (abhij) : Revert to trace logger
+            LOGGER.trace("{} {}\n{}", p0, p1, 
LogRedactionUtil.userData(SqlppAstPrintUtil.toString(topStatement)));
         }
     }

diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeSeqToSelectExprVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeSeqToSelectExprVisitor.java
index cd7b077..b0a10f7 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeSeqToSelectExprVisitor.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeSeqToSelectExprVisitor.java
@@ -45,13 +45,18 @@
 import org.apache.asterix.om.functions.BuiltinFunctions;

 /**
- * TODO (abhij) : Rewrite this comment
+ * ChangeSeqExpression has two encapsulating expressions:
+ * 1. priorExpr
+ * 2. currentExpr
+ * where semantically priorExpr feeds into currentExpr (priorExpr ---> 
currentExpr).
+ * This relation gets rewritten as:
+ * SELECT ELEMENT data-transform(currentExpr, <GENERATED_VAR>) FROM priorExpr 
AS <GENERATED_VAR>
+ *
  * Rewrites UPDATE, DELETE FROM and INSERT INTO expressions within the context
  * of a ChangeExpression to their SET fieldAccessor = SelectExpression 
counterpart.
  *
- * Note: This visit needs to be performed before any variable scoping visitor 
runs over
- * this expression. This is so that an appropriate variable can be tagged as 
CONTEXT_VARIABLE
- * for the VariableCheckAndRewriteVisitor
+ * Note: Very important to run this visitor before variableCheckAndRewrite so 
that the
+ * <GENERATED_VAR> can be used as the new ContextVariable for further 
operations in the chain of changes.
  */

 public final class SqlppChangeSeqToSelectExprVisitor extends 
AbstractSqlppExpressionScopingVisitor {
@@ -70,7 +75,7 @@
         Expression dataTransformRecord = changeExpr.getDataTransformRecord();

         VariableExpr newGeneratedVar = 
generateVarOverContext(rewrittenFirstExpr.getSourceLocation());
-        // TODO (abhij) : Figure out positional Variables
+        // TODO (abhij) : Is there a need to generate positional variables?
         FromTerm fromTerm = new FromTerm(rewrittenFirstExpr, newGeneratedVar, 
null, null);
         fromTerm.setSourceLocation(rewrittenFirstExpr.getSourceLocation());
         FromClause fromClause = new 
FromClause(Collections.singletonList(fromTerm));
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeToSetExpressionVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeToSetExpressionVisitor.java
index 8313921..a9540c8 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeToSetExpressionVisitor.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppChangeToSetExpressionVisitor.java
@@ -145,9 +145,6 @@
         updateExpr.setPathExpr(visit(updateExpr.getPathExpr(), updateExpr));

         // 2. Generate the SelectExpression as ValueExpr of SetElement
-        // TODO (abhij) : Remove this visitor. Recursive rewrites should be 
done only when the scoping is done on the
-        // FROM clause of this rewritten update
-        // updateExpr.setChangeSeq(super.visit(updateExpr.getChangeSeq(), 
arg));

         CallExpr sourceCollectionCallExpr = new CallExpr(new 
FunctionSignature(BuiltinFunctions.CHECK_LIST),
                 Collections.singletonList(updateExpr.getPathExpr()));
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
index db8b483..ff1bc13 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
@@ -539,49 +539,42 @@
         return copy;
     }

-    // TODO (abhij): Implement SetExpr visitor
+    /** Placeholder visitors as the rewrite visitors will eventually rewrite 
these constructs to other forms*/
     @Override
     public ILangExpression visit(SetElement setelem, Void arg) throws 
CompilationException {
         return setelem;
     }

-    // TODO (abhij): Implement SetExpr visitor
     @Override
     public ILangExpression visit(SetExpression setexpr, Void arg) throws 
CompilationException {
         return setexpr;
     }

-    // TODO (abhij): Implement UpdateExpression visitor
     @Override
     public ILangExpression visit(UpdateExpression updateexpr, Void arg) throws 
CompilationException {
         return updateexpr;
     }

-    // TODO (abhij): Implement DeleteExpression visitor
     @Override
     public ILangExpression visit(DeleteExpression deleteExpr, Void arg) throws 
CompilationException {
         return deleteExpr;
     }

-    // TODO (abhij): Implement InsertExpression visitor
     @Override
     public ILangExpression visit(InsertExpression insertExpr, Void arg) throws 
CompilationException {
         return insertExpr;
     }

-    // TODO (abhij): Implement ChangeExpression visitor
     @Override
     public ILangExpression visit(ChangeExpression changeExpr, Void arg) throws 
CompilationException {
         return changeExpr;
     }

-    // TODO (abhij): Implement ChangeExpression visitor
     @Override
     public ILangExpression visit(ChangeSeqExpression changeSeqExpr, Void arg) 
throws CompilationException {
         return changeSeqExpr;
     }

-    // TODO (abhij): Implement ChangeExpression visitor
     @Override
     public ILangExpression visit(ChangeSequenceWrapper changeSeqWapper, Void 
arg) throws CompilationException {
         return changeSeqWapper;
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
index 56f8d3d..1ba095f 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
@@ -526,8 +526,6 @@
         SymbolResolver resolver = new SymbolResolver(varName);
         scopeChecker.iterateSymbols(resolver);
         Identifier ident = resolver.getResolvedIdentifier();
-        // TODO (abhij) : Remove code
-        //Identifier ident = scopeChecker.lookupSymbol(varName);
         if (ident == null) {
             if (SqlppVariableUtil.isExternalVariableIdentifier(varId)) {
                 throw new CompilationException(ErrorCode.PARAMETER_NO_VALUE, 
varExpr.getSourceLocation(),
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
index 743c717..31330de 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
@@ -457,17 +457,15 @@
         return setexpr;
     }

-    // TODO (abhij) : Just run a simple iteration through the UpdateExpression
+    /** No need to look inside these expression types as these will be 
rewritten eventually */
     public Expression visit(UpdateExpression updateExpr, ILangExpression arg) 
throws CompilationException {
         return updateExpr;
     }

-    // TODO (abhij) : Just run a simple iteration through the DeleteExpression
     public Expression visit(DeleteExpression deleteExpr, ILangExpression arg) 
throws CompilationException {
         return deleteExpr;
     }

-    // TODO (abhij) : Just run a simple iteration through the InsertExpression
     public Expression visit(InsertExpression insertExpr, ILangExpression arg) 
throws CompilationException {
         return insertExpr;
     }
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/CheckIntegerDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/CheckIntegerDescriptor.java
index 23c9a41..d3f832f 100644
--- 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/CheckIntegerDescriptor.java
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/CheckIntegerDescriptor.java
@@ -59,7 +59,6 @@

                     @Override
                     public void evaluate(IFrameTupleReference tuple, 
IPointable result) throws HyracksDataException {
-                        // TODO (abhij) : Start using cast runtime
                         CastTypeEvaluator castEval =
                                 new CastTypeEvaluator(BuiltinType.AINT64, 
BuiltinType.ANY, eval, sourceLoc);
                         try {
diff --git 
a/hyracks-fullstack/algebricks/algebricks-runtime/src/main/java/org/apache/hyracks/algebricks/runtime/operators/meta/SubplanRuntimeFactory.java
 
b/hyracks-fullstack/algebricks/algebricks-runtime/src/main/java/org/apache/hyracks/algebricks/runtime/operators/meta/SubplanRuntimeFactory.java
index d712e86..2a1a638 100644
--- 
a/hyracks-fullstack/algebricks/algebricks-runtime/src/main/java/org/apache/hyracks/algebricks/runtime/operators/meta/SubplanRuntimeFactory.java
+++ 
b/hyracks-fullstack/algebricks/algebricks-runtime/src/main/java/org/apache/hyracks/algebricks/runtime/operators/meta/SubplanRuntimeFactory.java
@@ -187,6 +187,8 @@
                         nts.writeTuple(buffer, t);
                     } catch (HyracksDataException e) {
                         if (isFailSafe) {
+                            // TODO (abhij) : access the primary composite key 
from within tRef
+                            // TODO (abhij) : Invoke warning here with the 
primary keysets
                             continue tupleIterator;
                         }
                         throw e;

--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/19369
To unsubscribe, or for help writing mail filters, visit 
https://asterix-gerrit.ics.uci.edu/settings

Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Change-Id: I72b4d8fb6718cf5cf5431d755cd525fa546fd2be
Gerrit-Change-Number: 19369
Gerrit-PatchSet: 1
Gerrit-Owner: Abhishek Jindal <[email protected]>
Gerrit-MessageType: newchange

Reply via email to