Skip to content

Commit

Permalink
TEIID-5042 TEIID-5039 allowing for better datatype handling and updates
Browse files Browse the repository at this point in the history
with named types
  • Loading branch information
shawkins committed Sep 2, 2017
1 parent 81a10a1 commit 0c01da4
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ public void setValue(JsonObject json, String attr, Class<?> type, Object attrVal
json.put(attr, (BigDecimal)attrValue);
} else if(type.equals(TypeFacility.RUNTIME_TYPES.NULL)) {
json.putNull(attr);
} else {
json.put(attr, attrValue);
}
}

Expand All @@ -361,6 +363,8 @@ public void setValue(JsonArray array, Class<?> type, Object attrValue) {
array.add((BigDecimal)attrValue);
} else if(type.equals(TypeFacility.RUNTIME_TYPES.NULL)) {
array.addNull();
} else {
array.add(attrValue);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ private void scanObjectRow(String key, String keyInSource, JsonObject value, Met
if(columnType.equals(OBJECT)) {
JsonValue jsonValue = (JsonValue) columnValue;
String newKey = key + UNDERSCORE + columnName;
String newKeyInSource = keyInSource + SOURCE_SEPARATOR + this.nameInSource(columnName);
String newKeyInSource = keyInSource + SOURCE_SEPARATOR + nameInSource(columnName);

if(isObjectJsonType(columnValue)) {
scanRow(newKey, newKeyInSource, jsonValue, mf, table, referenceTableName, true, dimension);
Expand Down Expand Up @@ -294,7 +294,7 @@ private void scanArrayRow(String keyspace, String keyInSource, JsonArray array,
scanRow(keyspace, keyInSource, jsonValue, mf, table, referenceTableName, true, dimension);
} else if (isArrayJsonType(jsonValue)) {
String tableName = table.getName() + UNDERSCORE + name + UNDERSCORE + dimension.get();
String tableNameInSrc = table.getNameInSource() + SOURCE_SEPARATOR + this.nameInSource(name) + SQUARE_BRACKETS;
String tableNameInSrc = table.getNameInSource() + SOURCE_SEPARATOR + nameInSource(name) + SQUARE_BRACKETS;
Dimension d = new Dimension();
Table subTable = addTable(tableName, tableNameInSrc, true, referenceTableName, d, mf);
scanRow(keyspace, keyInSource, jsonValue, mf, subTable, referenceTableName, true, d);
Expand Down Expand Up @@ -424,10 +424,10 @@ private String buildArrayTableIdxName(String nameInSource, int dimension) {
for(String name : names) {
if(isFirst) {
isFirst = false;
sb.append(this.trimWave(name));
sb.append(trimWave(name));
} else {
sb.append(UNDERSCORE);
sb.append(this.trimWave(name));
sb.append(trimWave(name));
}
}

Expand Down Expand Up @@ -576,18 +576,18 @@ private String buildN1QLFrom(String namespace, String keyspace) {
return sb.toString();
}

private String trimWave(String value) {
static String trimWave(String value) {
String results = value;
if(results.startsWith(WAVE)) {
results = results.substring(1);
}
if(results.endsWith(WAVE)) {
results = results.substring(0, results.length() - 1);
if(results.startsWith(WAVE) && results.endsWith(WAVE)) {
results = results.substring(1, results.length() - 1);
}
return results;
}

private String nameInSource(String path) {
static String nameInSource(String path) {
if(path.startsWith(WAVE) && path.endsWith(WAVE)) {
return path;
}
return WAVE + path + WAVE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public static enum Event implements BundleUtil.Event{
TEIID29018,
TEIID29019,
TEIID29020,
TEIID29021
TEIID29021,
TEIID29022,
TEIID29023
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.teiid.language.SQLConstants.NonReserved.*;
import static org.teiid.language.SQLConstants.Reserved.*;
import static org.teiid.language.SQLConstants.Tokens.*;
import static org.teiid.translator.couchbase.CouchbaseMetadataProcessor.*;
import static org.teiid.translator.couchbase.CouchbaseProperties.*;

import java.util.ArrayList;
Expand All @@ -31,13 +32,16 @@
import org.teiid.core.util.StringUtil;
import org.teiid.language.*;
import org.teiid.language.SQLConstants.Tokens;
import org.teiid.metadata.Column;
import org.teiid.translator.TypeFacility;

import com.couchbase.client.java.document.json.JsonArray;
import com.couchbase.client.java.document.json.JsonObject;

public class N1QLUpdateVisitor extends N1QLVisitor {

private static final String ESCAPED_QUOTE = "\\u0027"; //$NON-NLS-1$

private int dimension = 0;

private String keyspace;
Expand All @@ -57,10 +61,15 @@ public void visit(Insert obj) {

List<CBColumnData> rowCache = new ArrayList<N1QLUpdateVisitor.CBColumnData>();

for (ColumnReference col : obj.getColumns()) {
Integer typeIndex = null;
for (int i = 0; i < obj.getColumns().size(); i++) {
ColumnReference col = obj.getColumns().get(i);
CBColumn column = formCBColumn(col);
CBColumnData cacheData = new CBColumnData(col.getType(), column);
rowCache.add(cacheData);
if(typedName != null && typedName.equals(nameInSource(cacheData.getCBColumn().getLeafName()))) {
typeIndex = i;
}
}

List<Parameter> preparedValues = new ArrayList<>();
Expand All @@ -70,9 +79,36 @@ public void visit(Insert obj) {
if(exp instanceof Literal) {
Literal l = (Literal)exp;
rowCache.get(i).setValue(l.getValue());
if (typeIndex != null && typeIndex == i && !typedValue.equals(getValueString(l.getType(), l.getValue()))) {
throw new TeiidRuntimeException(CouchbasePlugin.Event.TEIID29022, CouchbasePlugin.Util.gs(CouchbasePlugin.Event.TEIID29022, typedValue));
}
} else if(exp instanceof Parameter) {
Parameter p = (Parameter) exp;
preparedValues.add(p);
if (typeIndex != null && typeIndex == i) {
throw new TeiidRuntimeException(CouchbasePlugin.Event.TEIID29022, CouchbasePlugin.Util.gs(CouchbasePlugin.Event.TEIID29022, typedValue));
}
}
}

if (typedName != null && typeIndex == null) {
//add type
boolean added = false;
for (Column c : obj.getTable().getMetadataObject().getColumns()) {
if (!nameInSource(c.getSourceName()).endsWith(typedName)) {
continue;
}
ColumnReference cr = new ColumnReference(obj.getTable(), c.getName(), c, c.getJavaType());
CBColumn column = formCBColumn(cr);
CBColumnData cacheData = new CBColumnData(TypeFacility.RUNTIME_TYPES.STRING, column);
cacheData.setValue(getRawValue(typedValue));
rowCache.add(cacheData);
added = true;
break;
}
if (!added) {
//TODO: could support this without requiring a type column
throw new TeiidRuntimeException(CouchbasePlugin.Event.TEIID29023, CouchbasePlugin.Util.gs(CouchbasePlugin.Event.TEIID29023, typedName));
}
}

Expand Down Expand Up @@ -130,7 +166,10 @@ public void visit(Insert obj) {
CBColumnData columnData = rowCache.get(i);

if(columnData.getCBColumn().isPK()) {
documentID = (String)columnData.getValue();
Object value = columnData.getValue();
if (value != null) {
documentID = value.toString();
}
} else {
String attr = columnData.getCBColumn().getLeafName();
String path = columnData.getCBColumn().getNameInSource();
Expand Down Expand Up @@ -283,7 +322,7 @@ public void visit(NamedTable obj) {

retrieveTableProperty(obj);

String tableNameInSource = obj.getMetadataObject().getNameInSource();
String tableNameInSource = obj.getMetadataObject().getSourceName();

if(isArrayTable) {
this.keyspace = tableNameInSource.substring(0, tableNameInSource.indexOf(SOURCE_SEPARATOR));
Expand Down Expand Up @@ -478,7 +517,7 @@ private String getValueString(Class<?> type, Object value) {
}

if(type.equals(TypeFacility.RUNTIME_TYPES.STRING)) {
return SQLConstants.Tokens.QUOTE + StringUtil.replace(value.toString(), SQLConstants.Tokens.QUOTE, "\\u0027") + SQLConstants.Tokens.QUOTE; //$NON-NLS-1$
return SQLConstants.Tokens.QUOTE + StringUtil.replace(value.toString(), SQLConstants.Tokens.QUOTE, ESCAPED_QUOTE) + SQLConstants.Tokens.QUOTE;
} else if(type.equals(TypeFacility.RUNTIME_TYPES.INTEGER) || type.equals(TypeFacility.RUNTIME_TYPES.LONG)
|| type.equals(TypeFacility.RUNTIME_TYPES.DOUBLE) || type.equals(TypeFacility.RUNTIME_TYPES.DOUBLE)
|| type.equals(TypeFacility.RUNTIME_TYPES.BOOLEAN) || type.equals(TypeFacility.RUNTIME_TYPES.BIG_INTEGER)
Expand All @@ -488,6 +527,13 @@ private String getValueString(Class<?> type, Object value) {
throw new AssertionError("Unknown literal type: " + type); //$NON-NLS-1$
}

private String getRawValue(String value) {
if (value.startsWith(SQLConstants.Tokens.QUOTE) && value.endsWith(SQLConstants.Tokens.QUOTE)) {
return StringUtil.replace(value.substring(1, value.length() - 1), ESCAPED_QUOTE, SQLConstants.Tokens.QUOTE);
}
return value;
}

@Override
public void visit(Update obj) {

Expand All @@ -512,6 +558,12 @@ public void visit(Update obj) {
if (clause.getValue() instanceof Literal) {
value = ((Literal)clause.getValue()).getValue();
}
if(typedName != null && typedName.equals(nameInSource(cacheData.getCBColumn().getLeafName()))) {
if (!typedValue.equals(getValueString(cacheData.getColumnType(), value))) {
throw new TeiidRuntimeException(CouchbasePlugin.Event.TEIID29022, CouchbasePlugin.Util.gs(CouchbasePlugin.Event.TEIID29022, typedValue));
}
continue;
}
cacheData.setValue(value);
rowCache.add(cacheData);
}
Expand Down Expand Up @@ -622,27 +674,39 @@ private String getUsesKeyString(List<CBColumnData> rowCache) {


private void appendClauses(List<CBColumnData> rowCache, List<Condition> otherConditions, List<SetClause> setClauses) {
if (rowCache.isEmpty() && otherConditions.isEmpty()) {
return;
}

String useKey = this.getUsesKeyString(rowCache);

boolean isTypedInProjection = false;
boolean isTyped = false;

if (useKey != null) {
buffer.append(SPACE).append(useKey);
}

if (setClauses != null) {
buffer.append(SPACE).append(SET).append(SPACE);
for (SetClause clause : setClauses) {
ColumnReference col = clause.getSymbol();
CBColumn column = formCBColumn(col);
CBColumnData cacheData = new CBColumnData(col.getType(), column);
Object value = clause.getValue();
if (clause.getValue() instanceof Literal) {
value = ((Literal)clause.getValue()).getValue();
}
if(typedName != null && typedName.equals(nameInSource(cacheData.getCBColumn().getLeafName()))
&& (value == null || !typedValue.equals(getValueString(cacheData.getColumnType(), value)))) {
throw new TeiidRuntimeException(CouchbasePlugin.Event.TEIID29022, CouchbasePlugin.Util.gs(CouchbasePlugin.Event.TEIID29022, typedValue));
}
}
append(setClauses);
}

boolean hasPredicate = false;
for (CBColumnData columnData : rowCache) {
if(typedName != null && typedName.equals(nameInSource(columnData.getCBColumn().getLeafName()))) {
isTypedInProjection = true;
if (typedValue.equals(getValueString(columnData.getColumnType(), columnData.getValue()))) {
isTyped = true;
}
//else no rows affected
}
if (columnData.getCBColumn().isPK()) {
continue;
Expand All @@ -660,7 +724,7 @@ private void appendClauses(List<CBColumnData> rowCache, List<Condition> otherCon
buffer.append(getValueString(columnData.getColumnType(), columnData.getValue()));
}

boolean hasTypedValue = !isTypedInProjection && typedName != null && typedValue != null;
boolean hasTypedValue = !isTyped && typedName != null && typedValue != null;
if (!otherConditions.isEmpty()) {
if (!hasPredicate) {
buffer.append(SPACE).append(WHERE);
Expand Down Expand Up @@ -689,7 +753,7 @@ private void appendClauses(List<CBColumnData> rowCache, List<Condition> otherCon
}
}

private class CBColumnData {
private static class CBColumnData {

private Class<?> columnType;
private CBColumn column;
Expand Down
Loading

0 comments on commit 0c01da4

Please sign in to comment.