diff --git a/core/src/main/java/org/polypheny/db/type/PolyType.java b/core/src/main/java/org/polypheny/db/type/PolyType.java index 38e545ad9b..3760f9733a 100644 --- a/core/src/main/java/org/polypheny/db/type/PolyType.java +++ b/core/src/main/java/org/polypheny/db/type/PolyType.java @@ -236,6 +236,12 @@ public enum PolyType { Types.VARCHAR, PolyTypeFamily.CHARACTER ), + TEXT( + PrecScale.NO_NO, + false, + Types.VARCHAR, + PolyTypeFamily.CHARACTER ), + BINARY( PrecScale.NO_NO | PrecScale.YES_NO, false, diff --git a/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java b/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java index 5ffb42d0c5..d9c8cb0e17 100644 --- a/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java +++ b/core/src/main/java/org/polypheny/db/type/entity/PolyValue.java @@ -555,6 +555,10 @@ public PolyString asString() { } + public boolean isText() { + return type == PolyType.TEXT; + } + public boolean isBinary() { return type == PolyType.BINARY; } diff --git a/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java b/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java index 1d4cc135b9..af42d9d428 100644 --- a/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java +++ b/dbms/src/main/java/org/polypheny/db/PolyphenyDb.java @@ -124,7 +124,7 @@ public class PolyphenyDb { public boolean daemonMode = false; @Option(name = { "-defaultStore" }, description = "Type of default storeId") - public String defaultStoreName = "hsqldb"; + public String defaultStoreName = "mongodb"; @Option(name = { "-defaultSource" }, description = "Type of default source") public String defaultSourceName = "csv"; diff --git a/dbms/src/test/java/org/polypheny/db/TestHelper.java b/dbms/src/test/java/org/polypheny/db/TestHelper.java index 0b56964a37..9fc8fe4652 100644 --- a/dbms/src/test/java/org/polypheny/db/TestHelper.java +++ b/dbms/src/test/java/org/polypheny/db/TestHelper.java @@ -419,7 +419,10 @@ public static boolean checkDocResultSet( DocResult result, List expected fail(); throw new RuntimeException( "Should contain " + DocumentType.DOCUMENT_ID + " field." ); } - doc.remove( DocumentType.DOCUMENT_ID ); + if ( excludeId ) { + doc.remove( DocumentType.DOCUMENT_ID ); + } + } parsedResults.add( doc ); } diff --git a/dbms/src/test/java/org/polypheny/db/mql/AggregateTest.java b/dbms/src/test/java/org/polypheny/db/mql/AggregateTest.java index 7a89c55fff..b98922641c 100644 --- a/dbms/src/test/java/org/polypheny/db/mql/AggregateTest.java +++ b/dbms/src/test/java/org/polypheny/db/mql/AggregateTest.java @@ -228,9 +228,9 @@ public void groupSubFieldTest() { @Test public void groupAvgTest() { List expected = MongoConnection.arrayToDoc( List.of( - new Object[]{ "val2", 5 }, - new Object[]{ "val1", 7 } ), - "test", "avgValue" ); + new Object[]{ "val2", 5.0 }, + new Object[]{ "val1", 7.0 } ), + "_id", "avgValue" ); insertMany( DATA_1 ); DocResult result = aggregate( $group( diff --git a/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEntity.java b/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEntity.java index cfd5b23f87..4bdfc1e4d9 100644 --- a/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEntity.java +++ b/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEntity.java @@ -517,7 +517,7 @@ private long doDML( Operation operation, String filter, List operations, if ( !dataContext.getParameterValues().isEmpty() ) { assert operations.size() == 1; // prepared - MongoDynamic util = new MongoDynamic( BsonDocument.parse( operations.get( 0 ) ), bucket, dataContext, getEntity().getDataModel() ); + MongoDynamic util = MongoDynamic.create( BsonDocument.parse( operations.get( 0 ) ), bucket, dataContext, getEntity().getDataModel() ); List inserts = util.getAll( dataContext.getParameterValues() ); entity.getCollection().insertMany( session, inserts ); return inserts.size(); diff --git a/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEnumerator.java b/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEnumerator.java index cc4fa09679..1cf9d6a852 100644 --- a/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEnumerator.java +++ b/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/MongoEnumerator.java @@ -44,19 +44,26 @@ import org.apache.calcite.linq4j.function.Function1; import org.apache.commons.lang3.NotImplementedException; import org.bson.BsonDocument; +import org.bson.BsonType; import org.bson.BsonValue; import org.bson.Document; import org.polypheny.db.adapter.mongodb.util.MongoTupleType; import org.polypheny.db.catalog.exceptions.GenericRuntimeException; +import org.polypheny.db.type.PolyType; import org.polypheny.db.type.entity.PolyBigDecimal; +import org.polypheny.db.type.entity.PolyBinary; +import org.polypheny.db.type.entity.PolyBoolean; import org.polypheny.db.type.entity.PolyDate; +import org.polypheny.db.type.entity.PolyDouble; import org.polypheny.db.type.entity.PolyInteger; +import org.polypheny.db.type.entity.PolyList; import org.polypheny.db.type.entity.PolyLong; import org.polypheny.db.type.entity.PolyNull; import org.polypheny.db.type.entity.PolyString; import org.polypheny.db.type.entity.PolyTime; import org.polypheny.db.type.entity.PolyTimeStamp; import org.polypheny.db.type.entity.PolyValue; +import org.polypheny.db.type.entity.document.PolyDocument; /** @@ -232,6 +239,10 @@ static Function1 listGetter( final MongoTupleType type ) for ( MongoTupleType sub : type.subs ) { trans.add( o -> convert( o.asDocument().get( sub.name ), sub ) ); } + if ( type.type == PolyType.DOCUMENT ) { + trans.add( o -> convert( o, type ) ); + } + return e -> { BsonDocument doc = e.toBsonDocument(); @@ -251,6 +262,7 @@ private static PolyValue convert( BsonValue o, MongoTupleType type ) { if ( o == null || o.isNull() ) { return new PolyNull(); } + switch ( type.type ) { case BIGINT: return PolyLong.of( o.asNumber().longValue() ); @@ -268,6 +280,8 @@ private static PolyValue convert( BsonValue o, MongoTupleType type ) { return PolyTime.of( o.asNumber().longValue() ); case DATE: return PolyDate.of( o.asNumber().longValue() ); + case DOCUMENT: + return polyDocumentFromBson( o.asDocument() ); } throw new NotImplementedException(); @@ -301,5 +315,48 @@ private static PolyValue convert( BsonValue o, MongoTupleType type ) { } + private static PolyDocument polyDocumentFromBson( BsonDocument document ) { + PolyDocument doc = new PolyDocument(); + for ( String key : document.keySet() ) { + doc.put( PolyString.of( key ), convert( document.get( key ), document.get( key ).getBsonType() ) ); + } + return doc; + } + + + private static PolyValue convert( BsonValue value, BsonType bsonType ) { + switch ( bsonType ) { + case DOUBLE: + return PolyDouble.of( value.asDouble().getValue() ); + case STRING: + return PolyString.of( value.asString().getValue() ); + case DOCUMENT: + return polyDocumentFromBson( value.asDocument() ); + case ARRAY: + return PolyList.of( value.asArray().getValues().stream().map( v -> convert( v, v.getBsonType() ) ).toArray( PolyValue[]::new ) ); + case BINARY: + return PolyBinary.of( value.asBinary().getData() ); + case OBJECT_ID: + return PolyString.of( value.asObjectId().getValue().toHexString() ); + case BOOLEAN: + return PolyBoolean.of( value.asBoolean().getValue() ); + case DATE_TIME: + return PolyTimeStamp.of( value.asDateTime().getValue() ); + case NULL: + return PolyNull.NULL; + case INT32: + return PolyInteger.of( value.asInt32().getValue() ); + case TIMESTAMP: + return PolyTimeStamp.of( value.asTimestamp().getValue() ); + case INT64: + return PolyLong.of( value.asInt64().getValue() ); + case DECIMAL128: + return PolyBigDecimal.of( value.asDecimal128().decimal128Value().bigDecimalValue() ); + default: + throw new NotImplementedException(); + } + } + + } diff --git a/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/util/MongoDynamic.java b/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/util/MongoDynamic.java index 9c82915d05..abbcef5ffd 100644 --- a/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/util/MongoDynamic.java +++ b/plugins/mongodb-adapter/src/main/java/org/polypheny/db/adapter/mongodb/util/MongoDynamic.java @@ -57,7 +57,7 @@ public class MongoDynamic { private final Map> keyHandles = new HashMap<>(); // parent, index, private final Map> transformers = new HashMap<>(); - private final GridFSBucket bucket; + protected final GridFSBucket bucket; private final BsonDocument document; private final Map isRegexMap = new HashMap<>(); private final Map isFuncMap = new HashMap<>(); @@ -73,12 +73,15 @@ public MongoDynamic( BsonDocument document, GridFSBucket bucket, DataContext dat this.document = document.clone(); this.bucket = bucket; this.isProject = !document.isEmpty() && document.getFirstKey().equals( "$project" ); - if ( dataModel == DataModel.RELATIONAL ) { - this.document.forEach( ( k, bsonValue ) -> replaceDynamic( bsonValue, this.document, k, true, false ) ); - } else { - handleDynamic( this.document, new BsonString( "" ), "", true, false ); - } + this.document.forEach( ( k, bsonValue ) -> replaceDynamic( bsonValue, this.document, k, true, false ) ); + } + + public static MongoDynamic create( BsonDocument document, GridFSBucket bucket, DataContext dataContext, DataModel dataModel ) { + if ( dataModel == DataModel.DOCUMENT ) { + return new MongoDocumentDynamic( document, bucket, dataContext, DataModel.DOCUMENT ); + } + return new MongoDynamic( document, bucket, dataContext, DataModel.RELATIONAL ); } @@ -379,4 +382,20 @@ public void insert( BsonValue value ) { } + + public static class MongoDocumentDynamic extends MongoDynamic { + + public MongoDocumentDynamic( BsonDocument document, GridFSBucket bucket, DataContext dataContext, DataModel dataModel ) { + super( document, bucket, dataContext, dataModel ); + } + + + @Override + public List getAll( List> parameterValues ) { + return parameterValues.stream().flatMap( e -> e.entrySet().stream().map( v -> Document.parse( v.getValue().asDocument().toJson() ) ) ).collect( Collectors.toList() ); + } + + + } + }