Skip to content

Commit

Permalink
feat: SQL INSERT and CREATE VERTEX statements, support for json array
Browse files Browse the repository at this point in the history
Fixed issue #1257
  • Loading branch information
lvca committed Sep 29, 2023
1 parent 186c0ad commit 43e49a9
Show file tree
Hide file tree
Showing 11 changed files with 3,851 additions and 3,544 deletions.
27 changes: 26 additions & 1 deletion engine/src/main/grammar/SQLGrammar.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -1641,7 +1641,9 @@ InsertBody InsertBody():
|
( <CONTENT>
(
jjtThis.content = Json()
jjtThis.contentArray = JsonArray()
|
jjtThis.contentJson = Json()
|
jjtThis.contentInputParam = InputParameter()
)
Expand Down Expand Up @@ -3119,6 +3121,29 @@ Json Json():
}


JsonArray JsonArray():
{
Json lastItem;
Token token;
}
{
(
<LBRACKET>
[
lastItem = Json()
{
jjtThis.items = new ArrayList();
jjtThis.items.add(lastItem);
}
(
<COMMA>
lastItem = Json() { jjtThis.items.add(lastItem); }
)*
]
<RBRACKET>
)
{return jjtThis;}
}

MatchExpression MatchExpression():
{ MatchPathItem nextItem = null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ private void handleSetFields(final InsertExecutionPlan result, final InsertBody
if (insertBody.getIdentifierList() != null) {
result.chain(
new InsertValuesStep(insertBody.getIdentifierList(), insertBody.getValueExpressions(), context, profilingEnabled));
} else if (insertBody.getContent() != null) {
result.chain(new UpdateContentStep(insertBody.getContent(), context, profilingEnabled));
} else if (insertBody.getJsonContent() != null) {
result.chain(new UpdateContentStep(insertBody.getJsonContent(), context, profilingEnabled));
} else if (insertBody.getContentInputParam() != null) {
result.chain(new UpdateContentStep(insertBody.getContentInputParam(), context, profilingEnabled));
} else if (insertBody.getSetExpressions() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,29 @@ public InsertExecutionPlan createExecutionPlan(final CommandContext context, fin
return result;
}

private void handleSave(final InsertExecutionPlan result, final Identifier targetClusterName, final CommandContext context, final boolean profilingEnabled) {
private void handleSave(final InsertExecutionPlan result, final Identifier targetClusterName, final CommandContext context,
final boolean profilingEnabled) {
result.chain(new SaveElementStep(context, targetClusterName, profilingEnabled));
}

private void handleReturn(final InsertExecutionPlan result, final Projection returnStatement, final CommandContext context, final boolean profilingEnabled) {
private void handleReturn(final InsertExecutionPlan result, final Projection returnStatement, final CommandContext context,
final boolean profilingEnabled) {
if (returnStatement != null)
result.chain(new ProjectionCalculationStep(returnStatement, context, profilingEnabled));
}

private void handleSetFields(final InsertExecutionPlan result, final InsertBody insertBody, final CommandContext context, final boolean profilingEnabled) {
private void handleSetFields(final InsertExecutionPlan result, final InsertBody insertBody, final CommandContext context,
final boolean profilingEnabled) {
if (insertBody == null)
return;

if (insertBody.getIdentifierList() != null) {
result.chain(new InsertValuesStep(insertBody.getIdentifierList(), insertBody.getValueExpressions(), context, profilingEnabled));
} else if (insertBody.getContent() != null) {
result.chain(new UpdateContentStep(insertBody.getContent(), context, profilingEnabled));
result.chain(
new InsertValuesStep(insertBody.getIdentifierList(), insertBody.getValueExpressions(), context, profilingEnabled));
} else if (insertBody.getJsonContent() != null) {
result.chain(new UpdateContentStep(insertBody.getJsonContent(), context, profilingEnabled));
} else if (insertBody.getJsonArrayContent() != null) {
result.chain(new UpdateContentStep(insertBody.getJsonArrayContent(), context, profilingEnabled));
} else if (insertBody.getContentInputParam() != null) {
result.chain(new UpdateContentStep(insertBody.getContentInputParam(), context, profilingEnabled));
} else if (insertBody.getSetExpressions() != null) {
Expand All @@ -110,15 +116,19 @@ private void handleSetFields(final InsertExecutionPlan result, final InsertBody
}
}

private void handleTargetClass(final InsertExecutionPlan result, final Identifier targetClass, final CommandContext context, final boolean profilingEnabled) {
private void handleTargetClass(final InsertExecutionPlan result, final Identifier targetClass, final CommandContext context,
final boolean profilingEnabled) {
if (targetClass != null)
result.chain(new SetDocumentClassStep(targetClass, context, profilingEnabled));
}

private void handleCreateRecord(final InsertExecutionPlan result, final InsertBody body, final CommandContext context, final boolean profilingEnabled) {
private void handleCreateRecord(final InsertExecutionPlan result, final InsertBody body, final CommandContext context,
final boolean profilingEnabled) {
int tot = 1;
if (body != null && body.getValueExpressions() != null && body.getValueExpressions().size() > 0)
tot = body.getValueExpressions().size();
else if (body != null && body.getJsonArrayContent() != null && body.getJsonArrayContent().items.size() > 0)
tot = body.getJsonArrayContent().items.size();

if (targetType == null && targetBucket != null) {
final com.arcadedb.engine.Bucket bucket;
Expand All @@ -136,8 +146,8 @@ private void handleCreateRecord(final InsertExecutionPlan result, final InsertBo
result.chain(new CreateRecordStep(targetType.getStringValue(), context, tot, profilingEnabled));
}

private void handleInsertSelect(final InsertExecutionPlan result, final SelectStatement selectStatement, final CommandContext context,
final boolean profilingEnabled) {
private void handleInsertSelect(final InsertExecutionPlan result, final SelectStatement selectStatement,
final CommandContext context, final boolean profilingEnabled) {
final InternalExecutionPlan subPlan = selectStatement.createExecutionPlan(context, profilingEnabled);
result.chain(new SubQueryStep(subPlan, context, context, profilingEnabled));
if (targetType != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.arcadedb.exception.TimeoutException;
import com.arcadedb.query.sql.parser.InputParameter;
import com.arcadedb.query.sql.parser.Json;
import com.arcadedb.query.sql.parser.JsonArray;
import com.arcadedb.serializer.json.JSONArray;

import java.util.*;

Expand All @@ -32,13 +34,20 @@
*/
public class UpdateContentStep extends AbstractExecutionStep {
private Json json;
private JsonArray jsonArray;
private int arrayIndex = 0;
private InputParameter inputParameter;

public UpdateContentStep(final Json json, final CommandContext context, final boolean profilingEnabled) {
super(context, profilingEnabled);
this.json = json;
}

public UpdateContentStep(final JsonArray jsonArray, final CommandContext context, final boolean profilingEnabled) {
super(context, profilingEnabled);
this.jsonArray = jsonArray;
}

public UpdateContentStep(final InputParameter inputParameter, final CommandContext context, final boolean profilingEnabled) {
super(context, profilingEnabled);
this.inputParameter = inputParameter;
Expand All @@ -48,6 +57,7 @@ public UpdateContentStep(final InputParameter inputParameter, final CommandConte
public ResultSet syncPull(final CommandContext context, final int nRecords) throws TimeoutException {
final ResultSet upstream = getPrev().syncPull(context, nRecords);
return new ResultSet() {

@Override
public boolean hasNext() {
return upstream.hasNext();
Expand All @@ -56,6 +66,7 @@ public boolean hasNext() {
@Override
public Result next() {
final Result result = upstream.next();

if (result instanceof ResultInternal) {
if (!(result.getElement().get() instanceof Document))
((ResultInternal) result).setElement((Document) result.getElement().get().getRecord());
Expand All @@ -75,12 +86,15 @@ public void close() {
};
}

private boolean handleContent(final Document record, final CommandContext context) {
private void handleContent(final Document record, final CommandContext context) {
// REPLACE ALL THE CONTENT
final MutableDocument doc = record.modify();

if (json != null) {
doc.fromMap(json.toMap(record, context));
} else if (jsonArray != null && arrayIndex < jsonArray.items.size()) {
final Json jsonItem = jsonArray.items.get(arrayIndex++);
doc.fromMap(jsonItem.toMap(record, context));
} else if (inputParameter != null) {
final Object val = inputParameter.getValue(context.getInputParameters());
if (val instanceof Document) {
Expand All @@ -91,8 +105,6 @@ private boolean handleContent(final Document record, final CommandContext contex
throw new CommandExecutionException("Invalid value for UPDATE CONTENT: " + val);
}
}

return true;
}

@Override
Expand Down
31 changes: 22 additions & 9 deletions engine/src/main/java/com/arcadedb/query/sql/parser/InsertBody.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public class InsertBody extends SimpleNode {
protected List<Identifier> identifierList;
protected List<List<Expression>> valueExpressions;
protected List<InsertSetExpression> setExpressions;
protected Json content;
protected Json contentJson;
protected JsonArray contentArray;
protected InputParameter contentInputParam;

public InsertBody(final int id) {
Expand Down Expand Up @@ -82,9 +83,12 @@ public void toString(final Map<String, Object> params, final StringBuilder build
}
}

if (content != null) {
if (contentJson != null) {
builder.append("CONTENT ");
content.toString(params, builder);
contentJson.toString(params, builder);
} else if (contentArray != null) {
builder.append("CONTENT ");
contentArray.toString(params, builder);
} else if (contentInputParam != null) {
builder.append("CONTENT ");
contentInputParam.toString(params, builder);
Expand All @@ -96,9 +100,11 @@ public InsertBody copy() {
result.identifierList = identifierList == null ? null : identifierList.stream().map(x -> x.copy()).collect(Collectors.toList());
result.valueExpressions = valueExpressions == null ?
null :
valueExpressions.stream().map(sub -> sub.stream().map(x -> x.copy()).collect(Collectors.toList())).collect(Collectors.toList());
valueExpressions.stream().map(sub -> sub.stream().map(x -> x.copy()).collect(Collectors.toList()))
.collect(Collectors.toList());
result.setExpressions = setExpressions == null ? null : setExpressions.stream().map(x -> x.copy()).collect(Collectors.toList());
result.content = content == null ? null : content.copy();
result.contentJson = contentJson == null ? null : contentJson.copy();
result.contentArray = contentArray == null ? null : contentArray.copy();
result.contentInputParam = contentInputParam == null ? null : contentInputParam.copy();
return result;
}
Expand All @@ -118,7 +124,9 @@ public boolean equals(final Object o) {
return false;
if (!Objects.equals(setExpressions, that.setExpressions))
return false;
if (!Objects.equals(content, that.content))
if (!Objects.equals(contentJson, that.contentJson))
return false;
if (!Objects.equals(contentArray, that.contentArray))
return false;
return Objects.equals(contentInputParam, that.contentInputParam);
}
Expand All @@ -128,7 +136,8 @@ public int hashCode() {
int result = identifierList != null ? identifierList.hashCode() : 0;
result = 31 * result + (valueExpressions != null ? valueExpressions.hashCode() : 0);
result = 31 * result + (setExpressions != null ? setExpressions.hashCode() : 0);
result = 31 * result + (content != null ? content.hashCode() : 0);
result = 31 * result + (contentJson != null ? contentJson.hashCode() : 0);
result = 31 * result + (contentArray != null ? contentArray.hashCode() : 0);
result = 31 * result + (contentInputParam != null ? contentInputParam.hashCode() : 0);
return result;
}
Expand All @@ -145,8 +154,12 @@ public List<InsertSetExpression> getSetExpressions() {
return setExpressions;
}

public Json getContent() {
return content;
public Json getJsonContent() {
return contentJson;
}

public JsonArray getJsonArrayContent() {
return contentArray;
}

public InputParameter getContentInputParam() {
Expand Down
41 changes: 41 additions & 0 deletions engine/src/main/java/com/arcadedb/query/sql/parser/JsonArray.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* Generated By:JJTree: Do not edit this line. JsonArray.java Version 7.0 */
/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=true,NODE_PREFIX=,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.arcadedb.query.sql.parser;

import java.util.*;
import java.util.stream.*;

public class JsonArray extends SimpleNode {
public List<Json> items = new ArrayList<>();

public JsonArray(int id) {
super(id);
}

public void toString(final Map<String, Object> params, final StringBuilder builder) {
builder.append("[");
boolean first = true;
for (final Json item : items) {
if (!first) {
builder.append(", ");
}
item.toString(params, builder);

first = false;
}
builder.append("]");
}

public JsonArray copy() {
final JsonArray result = new JsonArray(-1);
result.items = items.stream().map(x -> x.copy()).collect(Collectors.toList());
return result;
}

@Override
protected Object[] getIdentityElements() {
return new Object[] { items };
}

}
/* JavaCC - OriginalChecksum=beafb9a5a435d346cad52bf835b7a2df (do not edit this line) */
Loading

0 comments on commit 43e49a9

Please sign in to comment.