1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Make source the same as branch 10.2

This commit is contained in:
Olivier Bertrand
2017-08-06 21:33:52 +02:00
parent bae30c93da
commit d66d149f0a
141 changed files with 41453 additions and 3031 deletions

View File

@@ -245,13 +245,10 @@ int main() {
ENDIF(CONNECT_WITH_ODBC)
#
# JDBC
# JDBC without MongoDB Java Driver
#
IF(APPLE)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine without JDBC support" OFF)
ELSE()
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
ENDIF()
# OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON)
IF(CONNECT_WITH_JDBC)
FIND_PACKAGE(Java 1.6)
@@ -262,7 +259,8 @@ IF(CONNECT_WITH_JDBC)
INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH2})
# SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) will be dynamically linked
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h
javaconn.cpp jdbconn.cpp tabjdbc.cpp
jdbccat.h javaconn.h jdbconn.h tabjdbc.h
JdbcInterface.java ApacheInterface.java MariadbInterface.java
MysqlInterface.java OracleInterface.java PostgresqlInterface.java
JavaWrappers.jar)
@@ -274,6 +272,13 @@ IF(CONNECT_WITH_JDBC)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/JavaWrappers.jar
DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine)
add_definitions(-DJDBC_SUPPORT)
IF(CONNECT_WITH_MONGO)
SET(CONNECT_SOURCES ${CONNECT_SOURCES}
jmgfam.cpp jmgoconn.cpp mongo.cpp tabjmg.cpp
jmgfam.h jmgoconn.h mongo.h tabjmg.h
Mongo2Interface.java Mongo3Interface.java)
add_definitions(-DMONGO_SUPPORT)
ENDIF()
ELSE()
SET(JDBC_LIBRARY "")
ENDIF()
@@ -292,27 +297,31 @@ IF(CONNECT_WITH_ZIP)
ENDIF(CONNECT_WITH_ZIP)
#
# MONGO (CMAKE NOT YET WORKING)
# MONGO C Driver (CMAKE NOT YET WORKING)
#
#OPTION(CONNECT_WITH_MONGO "Compile CONNECT storage engine with MONGO support" ON)
#IF(CONNECT_WITH_MONGO)
# IF(WIN32)
# # Adding some typical places to search in
# SET(PC_MONGO_INCLUDE_DIRS
# C:/mongo-c-driver/include
# D:/mongo-c-driver/include)
# D:/mongo-c-driver/include)
# SET(PC_MONGO_LIBRARY_DIRS
# C:/mongo-c-driver/lib
# D:/mongo-c-driver/lib)
# D:/mongo-c-driver/lib)
# ENDIF(WIN32)
# FIND_PACKAGE(libmongoc)
# FIND_PACKAGE(libmongoc 1.7)
# IF (MONGO_FOUND)
# INCLUDE_DIRECTORIES(${MONGO_INCLUDE_DIR})
# SET(MONGO_LIBRARY ${MONGO_LIBRARIES})
# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongofam.cpp mongofam.h)
# add_definitions(-DMONGO_SUPPORT)
# SET(CONNECT_SOURCES ${CONNECT_SOURCES}
# cmgoconn.cpp cmgfam.cpp tabcmg.cpp
# cmgoconn.h cmgfam.h tabcmg.h)
# add_definitions(-DCMGO_SUPPORT)
# IF (NOT JAVA_FOUND AND JNI_FOUND)
# SET(CONNECT_SOURCES ${CONNECT_SOURCES} mongo.cpp mongo.h)
# add_definitions(-DMONGO_SUPPORT)
# ENDIF (NOT JAVA_FOUND AND JNI_FOUND)
# ENDIF(MONGO_FOUND)
#ENDIF(CONNECT_WITH_MONGO)
@@ -339,3 +348,4 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES}
LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY})

Binary file not shown.

View File

@@ -0,0 +1,437 @@
package wrappers;
import java.util.Date;
import java.util.List;
import java.util.Set;
import com.mongodb.AggregationOptions;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.Cursor;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoException;
import com.mongodb.WriteConcernException;
import com.mongodb.WriteResult;
import com.mongodb.util.JSON;
public class Mongo2Interface {
boolean DEBUG = false;
String Errmsg = "No error";
Set<String> Colnames = null;
Cursor cursor = null;
MongoClient client = null;
DB db = null;
DBCollection coll = null;
BasicDBObject doc = null;
BasicDBObject dbq = null;
BasicDBObject dbf = null;
List<DBObject> pip = null;
AggregationOptions aop = null;
// === Constructors/finalize =========================================
public Mongo2Interface() {
this(false);
} // end of default constructor
public Mongo2Interface(boolean b) {
DEBUG = b;
} // end of constructor
protected void SetErrmsg(String str) {
if (DEBUG)
System.out.println(str);
Errmsg = str;
} // end of SetErrmsg
protected void SetErrmsg(Exception e) {
if (DEBUG)
System.out.println(e.getMessage());
Errmsg = e.toString();
} // end of SetErrmsg
public String GetErrmsg() {
String err = Errmsg;
Errmsg = "No error";
return err;
} // end of GetErrmsg
public int MongoConnect(String[] parms) {
int rc = 0;
if (DEBUG)
System.out.println("Mongo2: URI=" + parms[0] + " DB=" + parms[1]);
try {
MongoClientURI uri = new MongoClientURI(parms[0]);
client = new MongoClient(uri);
if (DEBUG)
System.out.println("Connection " + client.toString() + " established");
// Now connect to your databases
db = client.getDB(parms[1]);
if (parms[2] != null && !parms[2].isEmpty()) {
if (DEBUG)
System.out.println("user=" + parms[2] + " pwd=" + parms[3]);
@SuppressWarnings("deprecation")
boolean auth = db.authenticate(parms[2], parms[3].toCharArray());
if (DEBUG)
System.out.println("Authentication: " + auth);
} // endif user
} catch (MongoException me) {
SetErrmsg(me);
rc = -1;
} catch (Exception e) {
SetErrmsg(e);
rc = -3;
} // end try/catch
return rc;
} // end of MongoConnect
public int MongoDisconnect() {
int rc = 0;
try {
if (cursor != null) {
if (DEBUG)
System.out.println("Closing cursor");
cursor.close();
cursor = null;
} // endif client
if (client != null) {
if (DEBUG)
System.out.println("Closing connection");
client.close();
client = null;
} // endif client
} catch (MongoException se) {
SetErrmsg(se);
rc += 8;
} // end try/catch
return rc;
} // end of MongoDisconnect
public boolean GetCollection(String name) {
if (DEBUG)
System.out.println("GetCollection: name=" + name);
try {
coll = db.getCollection(name);
} catch (Exception e) {
SetErrmsg(e);
return true;
} // end try/catch
return false;
} // end of GetCollection
public long GetCollSize() {
return (coll != null) ? coll.count() : 0;
} // end of GetCollSize
public boolean FindColl(String query, String fields) {
if (DEBUG)
System.out.println("FindColl: query=" + query + " fields=" + fields);
try {
if (query != null || fields != null) {
dbq = (BasicDBObject) JSON.parse((query != null) ? query : "{}");
if (fields != null) {
dbf = (BasicDBObject) JSON.parse(fields);
cursor = coll.find(dbq, dbf);
} else
cursor = coll.find(dbq);
} else
cursor = coll.find();
} catch (Exception e) {
SetErrmsg(e);
return true;
} // end try/catch
return false;
} // end of FindColl
@SuppressWarnings("unchecked")
public boolean AggregateColl(String pipeline) {
if (DEBUG)
System.out.println("AggregateColl: pipeline=" + pipeline);
try {
DBObject pipe = (DBObject) JSON.parse(pipeline);
pip = (List<DBObject>) pipe.get("pipeline");
aop = AggregationOptions.builder().batchSize(0).allowDiskUse(true)
.outputMode(AggregationOptions.OutputMode.CURSOR).build();
cursor = coll.aggregate(pip, aop);
} catch (MongoException me) {
SetErrmsg(me);
return true;
} // end try/catch
return false;
} // end of AggregateColl
public boolean Rewind() {
if (cursor != null)
cursor.close();
if (pip == null) {
if (dbf != null)
cursor = coll.find(dbq, dbf);
else if (dbq != null)
cursor = coll.find(dbq);
else
cursor = coll.find();
} else
cursor = coll.aggregate(pip, aop);
return (cursor == null);
} // end of Rewind
public int ReadNext() {
try {
if (cursor.hasNext()) {
doc = (BasicDBObject) cursor.next();
if (DEBUG)
System.out.println("Class doc = " + doc.getClass());
Colnames = doc.keySet();
return 1;
} else
return 0;
} catch (MongoException me) {
SetErrmsg(me);
return -1;
} // end try/catch
} // end of ReadNext
public boolean Fetch(int row) {
if (cursor.hasNext()) {
doc = (BasicDBObject) cursor.next();
Colnames = doc.keySet();
return true;
} else
return false;
} // end of Fetch
public String GetDoc() {
return (doc != null) ? doc.toString() : null;
} // end of GetDoc
public Set<String> GetColumns() {
if (doc != null)
return doc.keySet();
else
return null;
} // end of GetColumns
public String ColumnDesc(int n, int[] val) {
// if (rsmd == null) {
// System.out.println("No result metadata");
// return null;
// } else try {
// val[0] = rsmd.getColumnType(n);
// val[1] = rsmd.getPrecision(n);
// val[2] = rsmd.getScale(n);
// val[3] = rsmd.isNullable(n);
// return rsmd.getColumnLabel(n);
// } catch (SQLException se) {
// SetErrmsg(se);
// } //end try/catch
return null;
} // end of ColumnDesc
protected Object GetFieldObject(String path) {
Object o = null;
BasicDBObject dob = null;
BasicDBList lst = null;
String[] names = null;
if (path == null || path.equals("*"))
return doc;
else if (doc instanceof BasicDBObject)
dob = doc;
// else if (o instanceof BasicDBList)
// lst = (BasicDBList) doc;
else
return doc;
try {
names = path.split("\\.");
for (String name : names) {
if (lst != null) {
o = lst.get(Integer.parseInt(name));
} else
o = dob.get(name);
if (o == null)
break;
if (DEBUG)
System.out.println("Class o = " + o.getClass());
if (o instanceof BasicDBObject) {
dob = (BasicDBObject) o;
lst = null;
} else if (o instanceof BasicDBList) {
lst = (BasicDBList) o;
} else
break;
} // endfor name
} catch (IndexOutOfBoundsException x) {
o = null;
} catch (MongoException se) {
SetErrmsg(se);
o = null;
} // end try/catch
return o;
} // end of GetFieldObject
public String GetField(String path) {
Object o = GetFieldObject(path);
if (o != null) {
if (o instanceof Date) {
Integer TS = (int) (((Date) o).getTime() / 1000);
return TS.toString();
} // endif Date
return o.toString();
} else
return null;
} // end of GetField
public Object MakeDocument() {
return new BasicDBObject();
} // end of MakeDocument
public boolean DocAdd(Object bdc, String key, Object val) {
try {
((BasicDBObject) bdc).append(key, val);
} catch (MongoException me) {
SetErrmsg(me);
return true;
} // end try/catch
return false;
} // end of DocAdd
public Object MakeArray() {
return new BasicDBList();
} // end of MakeArray
public boolean ArrayAdd(Object bar, int n, Object val) {
try {
((BasicDBList) bar).put(n, val);
} catch (MongoException me) {
SetErrmsg(me);
return true;
} catch (Exception ex) {
SetErrmsg(ex);
return true;
} // end try/catch
return false;
} // end of ArrayAdd
public boolean CollInsert(Object dob) {
try {
coll.insert((BasicDBObject) dob);
} catch (MongoException me) {
SetErrmsg(me);
return true;
} catch (Exception ex) {
SetErrmsg(ex);
return true;
} // end try/catch
return false;
} // end of CollInsert
public long CollUpdate(Object upd) {
long n = -1;
if (DEBUG)
System.out.println("upd: " + upd.toString());
try {
DBObject qry = new BasicDBObject("_id", doc.get("_id"));
WriteResult res = coll.update(qry, (DBObject) upd);
if (DEBUG)
System.out.println("CollUpdate: " + res.toString());
n = res.getN();
} catch (MongoException me) {
SetErrmsg(me);
} catch (Exception ex) {
SetErrmsg(ex);
} // end try/catch
return n;
} // end of CollUpdate
public long CollDelete(boolean all) {
long n = -1;
try {
WriteResult res;
BasicDBObject qry = new BasicDBObject();
if (!all)
qry.append("_id", doc.get("_id"));
res = coll.remove(qry);
if (DEBUG)
System.out.println("CollDelete: " + res.toString());
n = res.getN();
} catch (WriteConcernException wx) {
SetErrmsg(wx);
} catch (MongoException me) {
SetErrmsg(me);
} catch (UnsupportedOperationException ux) {
SetErrmsg(ux);
n = 0;
} // end try/catch
return n;
} // end of CollDelete
} // end of class MongoInterface

View File

@@ -0,0 +1,504 @@
package wrappers;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.bson.BsonArray;
import org.bson.BsonBoolean;
import org.bson.BsonDateTime;
import org.bson.BsonDocument;
import org.bson.BsonDouble;
import org.bson.BsonInt32;
import org.bson.BsonInt64;
import org.bson.BsonNull;
import org.bson.BsonString;
import org.bson.BsonValue;
import org.bson.Document;
import org.bson.conversions.Bson;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoException;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
public class Mongo3Interface {
boolean DEBUG = false;
String Errmsg = "No error";
Set<String> Colnames = null;
MongoClient client = null;
MongoDatabase db = null;
MongoCollection<BsonDocument> coll = null;
FindIterable<BsonDocument> finditer = null;
AggregateIterable<BsonDocument> aggiter = null;
MongoCursor<BsonDocument> cursor = null;
BsonDocument doc = null;
BsonDocument util = null;
BsonNull bsonull = new BsonNull();
// === Constructors/finalize =========================================
public Mongo3Interface() {
this(false);
} // end of default constructor
public Mongo3Interface(boolean b) {
DEBUG = b;
} // end of constructor
protected void SetErrmsg(String str) {
if (DEBUG)
System.out.println(str);
Errmsg = str;
} // end of SetErrmsg
protected void SetErrmsg(Exception e) {
if (DEBUG)
System.out.println(e.getMessage());
Errmsg = e.toString();
} // end of SetErrmsg
public String GetErrmsg() {
String err = Errmsg;
Errmsg = "No error";
return err;
} // end of GetErrmsg
public int MongoConnect(String[] parms) {
int rc = 0;
if (DEBUG)
System.out.println("Mongo3: URI=" + parms[0] + " DB=" + parms[1]);
try {
MongoClientURI uri = new MongoClientURI(parms[0]);
client = new MongoClient(uri);
if (DEBUG)
System.out.println("Connection " + client.toString() + " established");
// Now connect to your databases
db = client.getDatabase(parms[1]);
// if (parms[2] != null && !parms[2].isEmpty()) {
// if (DEBUG)
// System.out.println("user=" + parms[2] + " pwd=" + parms[3]);
// @SuppressWarnings("deprecation")
// boolean auth = db.authenticate(parms[2], parms[3].toCharArray());
// if (DEBUG)
// System.out.println("Authentication: " + auth);
// } // endif user
} catch (MongoException me) {
SetErrmsg(me);
rc = -1;
} catch (Exception e) {
SetErrmsg(e);
rc = -3;
} // end try/catch
return rc;
} // end of MongoConnect
public int MongoDisconnect() {
int rc = 0;
try {
if (cursor != null) {
if (DEBUG)
System.out.println("Closing cursor");
cursor.close();
cursor = null;
} // endif client
if (client != null) {
if (DEBUG)
System.out.println("Closing connection");
client.close();
client = null;
} // endif client
} catch (MongoException se) {
SetErrmsg(se);
rc += 8;
} // end try/catch
return rc;
} // end of MongoDisconnect
public boolean GetCollection(String name) {
if (DEBUG)
System.out.println("GetCollection: name=" + name);
try {
coll = db.getCollection(name).withDocumentClass(BsonDocument.class);
} catch (Exception e) {
SetErrmsg(e);
return true;
} // end try/catch
return false;
} // end of GetCollection
public long GetCollSize() {
return (coll != null) ? coll.count() : 0;
} // end of GetCollSize
public boolean FindColl(String query, String fields) {
if (DEBUG)
System.out.println("FindColl: query=" + query + " fields=" + fields);
try {
if (query != null) {
Bson dbq = Document.parse((query != null) ? query : "{}");
finditer = coll.find(dbq);
} else
finditer = coll.find();
if (fields != null) {
Bson dbf = BsonDocument.parse(fields);
finditer = finditer.projection(dbf);
} // endif fields
cursor = finditer.iterator();
} catch (Exception e) {
SetErrmsg(e);
return true;
} // end try/catch
return false;
} // end of FindColl
@SuppressWarnings("unchecked")
public boolean AggregateColl(String pipeline) {
if (DEBUG)
System.out.println("AggregateColl: pipeline=" + pipeline);
try {
Document pipe = Document.parse(pipeline);
ArrayList<?> pip = (ArrayList<?>) pipe.get("pipeline");
aggiter = coll.aggregate((List<? extends Bson>) pip);
cursor = aggiter.iterator();
} catch (MongoException me) {
SetErrmsg(me);
return true;
} // end try/catch
return false;
} // end of AggregateColl
public boolean Rewind() {
if (cursor != null)
cursor.close();
if (finditer != null)
cursor = finditer.iterator();
else if (aggiter != null)
cursor = aggiter.iterator();
return (cursor == null);
} // end of Rewind
public int ReadNext() {
if (cursor.hasNext()) {
doc = cursor.next();
if (DEBUG)
System.out.println("Class doc = " + doc.getClass());
Colnames = doc.keySet();
return 1;
} else
return 0;
} // end of ReadNext
public boolean Fetch(int row) {
if (cursor.hasNext()) {
doc = cursor.next();
Colnames = doc.keySet();
return true;
} else
return false;
} // end of Fetch
public String GetDoc() {
return (doc != null) ? doc.toJson() : null;
} // end of GetDoc
public Set<String> GetColumns() {
if (doc != null)
return doc.keySet();
else
return null;
} // end of GetColumns
public String ColumnName(int n) {
int i = 1;
for (String name : Colnames)
if (i++ == n)
return name;
return null;
} // end of ColumnName
public int ColumnType(int n, String name) {
// if (rsmd == null) {
// System.out.println("No result metadata");
// } else try {
// if (n == 0)
// n = rs.findColumn(name);
// return rsmd.getColumnType(n);
// } catch (SQLException se) {
// SetErrmsg(se);
// } //end try/catch
return 666; // Not a type
} // end of ColumnType
public String ColumnDesc(int n, int[] val) {
// if (rsmd == null) {
// System.out.println("No result metadata");
// return null;
// } else try {
// val[0] = rsmd.getColumnType(n);
// val[1] = rsmd.getPrecision(n);
// val[2] = rsmd.getScale(n);
// val[3] = rsmd.isNullable(n);
// return rsmd.getColumnLabel(n);
// } catch (SQLException se) {
// SetErrmsg(se);
// } //end try/catch
return null;
} // end of ColumnDesc
protected BsonValue GetFieldObject(String path) {
BsonValue o = doc;
BsonDocument dob = null;
BsonArray ary = null;
String[] names = null;
if (path == null || path.equals("*"))
return doc;
else if (o instanceof BsonDocument)
dob = doc;
else if (o instanceof BsonArray)
ary = (BsonArray) o;
else
return doc;
try {
names = path.split("\\.");
for (String name : names) {
if (ary != null) {
o = ary.get(Integer.parseInt(name));
} else
o = dob.get(name);
if (o == null)
break;
if (DEBUG)
System.out.println("Class o = " + o.getClass());
if (o instanceof BsonDocument) {
dob = (BsonDocument) o;
ary = null;
} else if (o instanceof BsonArray) {
ary = (BsonArray) o;
} else
break;
} // endfor name
} catch (IndexOutOfBoundsException x) {
o = null;
} catch (MongoException me) {
SetErrmsg(me);
o = null;
} // end try/catch
return o;
} // end of GetFieldObject
public String GetField(String path) {
BsonValue o = GetFieldObject(path);
if (o != null) {
if (o.isString()) {
return o.asString().getValue();
} else if (o.isInt32()) {
return Integer.toString(o.asInt32().getValue());
} else if (o.isInt64()) {
return Long.toString(o.asInt64().getValue());
} else if (o.isObjectId()) {
return o.asObjectId().getValue().toString();
} else if (o.isDateTime()) {
Integer TS = (int) (o.asDateTime().getValue() / 1000);
return TS.toString();
} else if (o.isDouble()) {
return Double.toString(o.asDouble().getValue());
} else if (o.isDocument()) {
return o.asDocument().toJson();
} else if (o.isArray()) {
util = new BsonDocument("arr", o.asArray());
String s = util.toJson();
int i1 = s.indexOf('[');
int i2 = s.lastIndexOf(']');
return s.substring(i1, i2 + 1);
} else if (o.isNull()) {
return null;
} else
return o.toString();
} else
return null;
} // end of GetField
protected BsonValue ObjToBson(Object val) {
BsonValue bval = null;
if (val == null)
bval = bsonull;
else if (val.getClass() == String.class)
bval = new BsonString((String) val);
else if (val.getClass() == Integer.class)
bval = new BsonInt32((int) val);
else if (val.getClass() == Double.class)
bval = new BsonDouble((double) val);
else if (val.getClass() == BigInteger.class)
bval = new BsonInt64((long) val);
else if (val.getClass() == Boolean.class)
bval = new BsonBoolean((Boolean) val);
else if (val.getClass() == Date.class)
bval = new BsonDateTime(((Date) val).getTime() * 1000);
else if (val.getClass() == BsonDocument.class)
bval = (BsonDocument) val;
else if (val.getClass() == BsonArray.class)
bval = (BsonArray) val;
return bval;
} // end of ObjToBson
public Object MakeDocument() {
return new BsonDocument();
} // end of MakeDocument
public boolean DocAdd(Object bdc, String key, Object val) {
try {
((BsonDocument) bdc).append(key, ObjToBson(val));
} catch (MongoException me) {
SetErrmsg(me);
return true;
} // end try/catch
return false;
} // end of DocAdd
public Object MakeArray() {
return new BsonArray();
} // end of MakeArray
public boolean ArrayAdd(Object bar, int n, Object val) {
try {
for (int i = ((BsonArray) bar).size(); i < n; i++)
((BsonArray) bar).add(bsonull);
((BsonArray) bar).add(ObjToBson(val));
} catch (MongoException me) {
SetErrmsg(me);
return true;
} catch (Exception ex) {
SetErrmsg(ex);
return true;
} // end try/catch
return false;
} // end of ArrayAdd
public boolean CollInsert(Object dob) {
try {
coll.insertOne((BsonDocument) dob);
} catch (MongoException me) {
SetErrmsg(me);
return true;
} catch (Exception ex) {
SetErrmsg(ex);
return true;
} // end try/catch
return false;
} // end of CollInsert
public long CollUpdate(Object upd) {
long n = -1;
if (DEBUG)
System.out.println("upd: " + upd.toString());
try {
UpdateResult res = coll.updateOne(Filters.eq("_id", doc.get("_id")), (Bson) upd);
if (DEBUG)
System.out.println("CollUpdate: " + res.toString());
n = res.getModifiedCount();
} catch (MongoException me) {
SetErrmsg(me);
} catch (Exception ex) {
SetErrmsg(ex);
} // end try/catch
return n;
} // end of CollUpdate
public long CollDelete(boolean all) {
long n = -1;
try {
DeleteResult res;
if (all)
res = coll.deleteMany(new Document());
else
res = coll.deleteOne(Filters.eq("_id", doc.get("_id")));
if (DEBUG)
System.out.println("CollDelete: " + res.toString());
n = res.getDeletedCount();
} catch (MongoException me) {
SetErrmsg(me);
} catch (Exception ex) {
SetErrmsg(ex);
} // end try/catch
return n;
} // end of CollDelete
} // end of class MongoInterface

View File

@@ -519,7 +519,7 @@ bool ARRAY::FilTest(PGLOBAL g, PVAL valp, OPVAL opc, int opm)
} else if (opc != OP_EXIST) {
sprintf(g->Message, MSG(MISSING_ARG), opc);
throw TYPE_ARRAY;
throw (int)TYPE_ARRAY;
} else // OP_EXIST
return Nval > 0;
@@ -681,14 +681,14 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
{
if (Vblp == NULL) {
strcpy(g->Message, MSG(PREC_VBLP_NULL));
throw TYPE_ARRAY;
throw (int)TYPE_ARRAY;
} // endif Vblp
bool was = Vblp->IsCi();
if (was && !p) {
strcpy(g->Message, MSG(BAD_SET_CASE));
throw TYPE_ARRAY;
throw (int)TYPE_ARRAY;
} // endif Vblp
if (was || !p)
@@ -699,7 +699,7 @@ void ARRAY::SetPrecision(PGLOBAL g, int p)
if (!was && Type == TYPE_STRING)
// Must be resorted to eliminate duplicate strings
if (Sort(g))
throw TYPE_ARRAY;
throw (int)TYPE_ARRAY;
} // end of SetPrecision

271
storage/connect/cmgfam.cpp Normal file
View File

@@ -0,0 +1,271 @@
/************** CMGFAM C++ Program Source Code File (.CPP) *************/
/* PROGRAM NAME: cmgfam.cpp */
/* ------------- */
/* Version 1.4 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 20017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
/* This program are the MongoDB access method classes. */
/* */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* filamtxt.h is header containing the file AM classes declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "tabjson.h"
#include "cmgfam.h"
#if defined(UNIX) || defined(UNIV_LINUX)
#include "osutil.h"
#endif
/* --------------------------- Class CMGFAM -------------------------- */
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
CMGFAM::CMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
{
Cmgp = NULL;
Pcg.Tdbp = NULL;
if (tdp) {
Pcg.Uristr = tdp->Uri;
Pcg.Db_name = tdp->Schema;
Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
} else {
Pcg.Uristr = NULL;
Pcg.Db_name = NULL;
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
Pcg.Pipe = false;
} // endif tdp
To_Fbt = NULL;
Mode = MODE_ANY;
Done = false;
Lrecl = tdp->Lrecl + tdp->Ending;
} // end of CMGFAM standard constructor
CMGFAM::CMGFAM(PCMGFAM tdfp) : DOSFAM(tdfp)
{
Pcg = tdfp->Pcg;
To_Fbt = tdfp->To_Fbt;
Mode = tdfp->Mode;
Done = tdfp->Done;
} // end of CMGFAM copy constructor
/***********************************************************************/
/* Reset: reset position values at the beginning of file. */
/***********************************************************************/
void CMGFAM::Reset(void)
{
TXTFAM::Reset();
Fpos = Tpos = Spos = 0;
} // end of Reset
/***********************************************************************/
/* MGO GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
int CMGFAM::GetFileLength(PGLOBAL g)
{
return 0;
} // end of GetFileLength
/***********************************************************************/
/* Cardinality: returns the number of documents in the collection. */
/* This function can be called with a null argument to test the */
/* availability of Cardinality implementation (1 yes, 0 no). */
/***********************************************************************/
int CMGFAM::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
return (!Init(g)) ? Cmgp->CollSize(g) : 0;
} // end of Cardinality
/***********************************************************************/
/* Note: This function is not really implemented yet. */
/***********************************************************************/
int CMGFAM::MaxBlkSize(PGLOBAL, int s)
{
return s;
} // end of MaxBlkSize
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
bool CMGFAM::Init(PGLOBAL g)
{
if (Done)
return false;
/*********************************************************************/
/* Open an C connection for this table. */
/*********************************************************************/
if (!Cmgp) {
Pcg.Tdbp = Tdbp;
Cmgp = new(g) CMgoConn(g, &Pcg);
} else if (Cmgp->IsConnected())
Cmgp->Close();
if (Cmgp->Connect(g))
return true;
Done = true;
return false;
} // end of Init
/***********************************************************************/
/* OpenTableFile: Open a MongoDB table. */
/***********************************************************************/
bool CMGFAM::OpenTableFile(PGLOBAL g)
{
Mode = Tdbp->GetMode();
if (Pcg.Pipe && Mode != MODE_READ) {
strcpy(g->Message, "Pipeline tables are read only");
return true;
} // endif Pipe
if (Init(g))
return true;
if (Mode == MODE_DELETE && !Tdbp->GetNext())
// Delete all documents
return Cmgp->DocDelete(g);
else if (Mode == MODE_INSERT)
Cmgp->MakeColumnGroups(g);
return false;
} // end of OpenTableFile
/***********************************************************************/
/* GetRowID: return the RowID of last read record. */
/***********************************************************************/
int CMGFAM::GetRowID(void)
{
return Rows;
} // end of GetRowID
/***********************************************************************/
/* GetPos: return the position of last read record. */
/***********************************************************************/
int CMGFAM::GetPos(void)
{
return Fpos;
} // end of GetPos
/***********************************************************************/
/* GetNextPos: return the position of next record. */
/***********************************************************************/
int CMGFAM::GetNextPos(void)
{
return Fpos; // TODO
} // end of GetNextPos
/***********************************************************************/
/* SetPos: Replace the table at the specified position. */
/***********************************************************************/
bool CMGFAM::SetPos(PGLOBAL g, int pos)
{
Fpos = pos;
Placed = true;
return false;
} // end of SetPos
/***********************************************************************/
/* Record file position in case of UPDATE or DELETE. */
/***********************************************************************/
bool CMGFAM::RecordPos(PGLOBAL g)
{
strcpy(g->Message, "CMGFAM::RecordPos NIY");
return true;
} // end of RecordPos
/***********************************************************************/
/* Initialize Fpos and the current position for indexed DELETE. */
/***********************************************************************/
int CMGFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
strcpy(g->Message, "CMGFAM::InitDelete NIY");
return RC_FX;
} // end of InitDelete
/***********************************************************************/
/* Skip one record in file. */
/***********************************************************************/
int CMGFAM::SkipRecord(PGLOBAL g, bool header)
{
return RC_OK; // Dummy
} // end of SkipRecord
/***********************************************************************/
/* ReadBuffer: Get next document from a collection. */
/***********************************************************************/
int CMGFAM::ReadBuffer(PGLOBAL g)
{
int rc = Cmgp->ReadNext(g);
if (rc != RC_OK)
return rc;
strncpy(Tdbp->GetLine(), Cmgp->GetDocument(g), Lrecl);
return RC_OK;
} // end of ReadBuffer
/***********************************************************************/
/* WriteBuffer: File write routine for MGO access method. */
/***********************************************************************/
int CMGFAM::WriteBuffer(PGLOBAL g)
{
return Cmgp->Write(g);
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for MGO and BLK access methods. */
/***********************************************************************/
int CMGFAM::DeleteRecords(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
} // end of DeleteRecords
/***********************************************************************/
/* Table file close routine for MGO access method. */
/***********************************************************************/
void CMGFAM::CloseTableFile(PGLOBAL g, bool)
{
Cmgp->Close();
Done = false;
} // end of CloseTableFile
/***********************************************************************/
/* Rewind routine for MGO access method. */
/***********************************************************************/
void CMGFAM::Rewind(void)
{
Cmgp->Rewind();
} // end of Rewind

65
storage/connect/cmgfam.h Normal file
View File

@@ -0,0 +1,65 @@
/*************** CMGFam H Declares Source Code File (.H) ***************/
/* Name: cmgfam.h Version 1.5 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the MongoDB access method classes declares. */
/***********************************************************************/
#include "cmgoconn.h"
typedef class TXTFAM *PTXF;
typedef class CMGFAM *PCMGFAM;
typedef class MGODEF *PMGODEF;
typedef class TDBCMG *PTDBCMG;
/***********************************************************************/
/* This is the MongoDB Access Method class declaration. */
/***********************************************************************/
class DllExport CMGFAM : public DOSFAM {
friend void mongo_init(bool);
public:
// Constructor
CMGFAM(PJDEF tdp);
CMGFAM(PCMGFAM txfp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
virtual bool GetUseTemp(void) { return false; }
virtual int GetPos(void);
virtual int GetNextPos(void);
void SetTdbp(PTDBDOS tdbp) { Tdbp = tdbp; }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) CMGFAM(this); }
void SetLrecl(int lrecl) { Lrecl = lrecl; }
// Methods
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g) { return false; }
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
virtual bool SetPos(PGLOBAL g, int recpos);
virtual int SkipRecord(PGLOBAL g, bool header);
virtual bool OpenTableFile(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void);
protected:
virtual bool OpenTempFile(PGLOBAL g) { return false; }
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b) { return false; }
virtual int RenameTempFile(PGLOBAL g) { return RC_OK; }
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
bool Init(PGLOBAL g);
// Members
CMgoConn *Cmgp; // Points to a C Mongo connection class
CMGOPARM Pcg; // Parms passed to Cmgp
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
bool Done; // Init done
}; // end of class CMGFAM

View File

@@ -0,0 +1,935 @@
/************ CMgoConn C++ Functions Source Code File (.CPP) ***********/
/* Name: CMgoConn.CPP Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the MongoDB C connection classes functions. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
/***********************************************************************/
/* Required objects includes. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "colblk.h"
#include "xobject.h"
#include "xtable.h"
#include "filter.h"
#include "cmgoconn.h"
bool IsNum(PSZ s);
// Required to initialize libmongoc's internals
void mongo_init(bool init)
{
if (init)
mongoc_init();
else
mongoc_cleanup();
} // end of mongo_init
/* --------------------------- Class INCOL --------------------------- */
/***********************************************************************/
/* Add a column in the column list. */
/***********************************************************************/
void INCOL::AddCol(PGLOBAL g, PCOL colp, char *jp)
{
char *p;
PKC kp, kcp;
if ((p = strchr(jp, '.'))) {
PINCOL icp;
*p++ = 0;
for (kp = Klist; kp; kp = kp->Next)
if (kp->Incolp && !strcmp(jp, kp->Key))
break;
if (!kp) {
icp = new(g) INCOL(IsNum(p));
kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
kcp->Next = NULL;
kcp->Incolp = icp;
kcp->Colp = NULL;
kcp->Key = PlugDup(g, jp);
if (Klist) {
for (kp = Klist; kp->Next; kp = kp->Next);
kp->Next = kcp;
} else
Klist = kcp;
} else
icp = kp->Incolp;
*(p - 1) = '.';
icp->AddCol(g, colp, p);
} else {
kcp = (PKC)PlugSubAlloc(g, NULL, sizeof(KEYCOL));
kcp->Next = NULL;
kcp->Incolp = NULL;
kcp->Colp = colp;
kcp->Key = jp;
if (Klist) {
for (kp = Klist; kp->Next; kp = kp->Next);
kp->Next = kcp;
} else
Klist = kcp;
} // endif jp
} // end of AddCol
/***********************************************************************/
/* Clear. */
/***********************************************************************/
void INCOL::Init(void)
{
bson_init(Child);
for (PKC kp = Klist; kp; kp = kp->Next)
if (kp->Incolp)
kp->Incolp->Init();
} // end of init
/***********************************************************************/
/* Destroy. */
/***********************************************************************/
void INCOL::Destroy(void)
{
bson_destroy(Child);
for (PKC kp = Klist; kp; kp = kp->Next)
if (kp->Incolp)
kp->Incolp->Destroy();
} // end of Destroy
/* -------------------------- Class CMgoConn ------------------------- */
/***********************************************************************/
/* Implementation of the CMgoConn class. */
/***********************************************************************/
CMgoConn::CMgoConn(PGLOBAL g, PCPARM pcg)
{
Pcg = pcg;
Uri = NULL;
Pool = NULL;
Client = NULL;
Database = NULL;
Collection = NULL;
Cursor = NULL;
Query = NULL;
Opts = NULL;
Fpc = NULL;
fp = NULL;
m_Connected = false;
} // end of CMgoConn standard constructor
/***********************************************************************/
/* Connect to the MongoDB server and get the collection. */
/***********************************************************************/
bool CMgoConn::Connect(PGLOBAL g)
{
Uri = mongoc_uri_new(Pcg->Uristr);
if (!Uri) {
sprintf(g->Message, "Failed to parse URI: \"%s\"", Pcg->Uristr);
return true;
} // endif Uri
// Create a new client pool instance
Pool = mongoc_client_pool_new(Uri);
mongoc_client_pool_set_error_api(Pool, 2);
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
mongoc_client_pool_set_appname(Pool, "Connect");
// Create a new client instance
Client = mongoc_client_pool_pop(Pool);
if (!Client) {
sprintf(g->Message, "Failed to get Client");
return true;
} // endif Client
// Get a handle on the collection Coll_name
Collection = mongoc_client_get_collection(Client, Pcg->Db_name, Pcg->Coll_name);
if (!Collection) {
sprintf(g->Message, "Failed to get Collection %s.%s",
Pcg->Db_name, Pcg->Coll_name);
return true;
} // endif Collection
/*********************************************************************/
/* Link a Fblock. This make possible to automatically close it */
/* in case of error (throw). */
/*********************************************************************/
PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;
fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
fp->Type = TYPE_FB_MONGO;
fp->Fname = NULL;
fp->Next = dbuserp->Openlist;
dbuserp->Openlist = fp;
fp->Count = 1;
fp->Length = 0;
fp->Memory = NULL;
fp->Mode = MODE_ANY;
fp->File = this;
fp->Handle = 0;
m_Connected = true;
return false;
} // end of Connect
/***********************************************************************/
/* CollSize: returns the number of documents in the collection. */
/***********************************************************************/
int CMgoConn::CollSize(PGLOBAL g)
{
int cnt;
bson_t *query;
const char *jf = NULL;
if (Pcg->Pipe)
return 10;
else if (Pcg->Filter)
jf = Pcg->Filter;
if (jf) {
query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
if (!query) {
htrc("Wrong filter: %s", Error.message);
return 10;
} // endif Query
} else
query = bson_new();
cnt = (int)mongoc_collection_count(Collection,
MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
if (cnt < 0) {
htrc("Collection count: %s", Error.message);
cnt = 2;
} // endif Cardinal
bson_destroy(query);
return cnt;
} // end of CollSize
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
bool CMgoConn::MakeCursor(PGLOBAL g)
{
const char *p;
bool id, b = false, all = false;
PCSZ options = Pcg->Options;
PTDB tp = Pcg->Tdbp;
PCOL cp;
PSTRG s = NULL;
id = (tp->GetMode() != MODE_READ);
if (options && !stricmp(options, "all")) {
options = NULL;
all = true;
} // endif Options
for (cp = tp->GetColumns(); cp; cp = cp->GetNext())
if (!strcmp(cp->GetName(), "_id"))
id = true;
else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !options)
all = true;
if (Pcg->Pipe) {
if (trace)
htrc("Pipeline: %s\n", options);
p = strrchr(options, ']');
if (!p) {
strcpy(g->Message, "Missing ] in pipeline");
return true;
} else
*(char*)p = 0;
s = new(g) STRING(g, 1023, (PSZ)options);
if (tp->GetFilter()) {
s->Append(",{\"$match\":");
if (tp->GetFilter()->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return true;
} else
s->Append('}');
tp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
if (!all && tp->GetColumns()) {
// Project list
s->Append(",{\"$project\":{\"");
if (!id)
s->Append("_id\":0,\"");
for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
if (b)
s->Append(",\"");
else
b = true;
s->Append(cp->GetJpath(g, true));
s->Append("\":1");
} // endfor cp
s->Append("}}");
} // endif all
s->Append("]}");
s->Resize(s->GetLength() + 1);
*(char*)p = ']'; // Restore Colist for discovery
p = s->GetStr();
if (trace)
htrc("New Pipeline: %s\n", p);
Query = bson_new_from_json((const uint8_t *)p, -1, &Error);
if (!Query) {
sprintf(g->Message, "Wrong pipeline: %s", Error.message);
return true;
} // endif Query
Cursor = mongoc_collection_aggregate(Collection, MONGOC_QUERY_NONE,
Query, NULL, NULL);
if (mongoc_cursor_error(Cursor, &Error)) {
sprintf(g->Message, "Mongo aggregate Failure: %s", Error.message);
return true;
} // endif error
} else {
if (Pcg->Filter || tp->GetFilter()) {
if (trace) {
if (Pcg->Filter)
htrc("Filter: %s\n", Pcg->Filter);
if (tp->GetFilter()) {
char buf[512];
tp->GetFilter()->Prints(g, buf, 511);
htrc("To_Filter: %s\n", buf);
} // endif To_Filter
} // endif trace
s = new(g) STRING(g, 1023, (PSZ)Pcg->Filter);
if (tp->GetFilter()) {
if (Pcg->Filter)
s->Append(',');
if (tp->GetFilter()->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return NULL;
} // endif Selector
tp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
if (trace)
htrc("selector: %s\n", s->GetStr());
s->Resize(s->GetLength() + 1);
Query = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
if (!Query) {
sprintf(g->Message, "Wrong filter: %s", Error.message);
return NULL;
} // endif Query
} else
Query = bson_new();
if (!all) {
if (options && *options) {
if (trace)
htrc("options=%s\n", options);
p = options;
} else if (tp->GetColumns()) {
// Projection list
if (s)
s->Set("{\"projection\":{\"");
else
s = new(g) STRING(g, 511, "{\"projection\":{\"");
if (!id)
s->Append("_id\":0,\"");
for (cp = tp->GetColumns(); cp; cp = cp->GetNext()) {
if (b)
s->Append(",\"");
else
b = true;
s->Append(cp->GetJpath(g, true));
s->Append("\":1");
} // endfor cp
s->Append("}}");
s->Resize(s->GetLength() + 1);
p = s->GetStr();
} else {
// count(*) ?
p = "{\"projection\":{\"_id\":1}}";
} // endif Options
Opts = bson_new_from_json((const uint8_t *)p, -1, &Error);
if (!Opts) {
sprintf(g->Message, "Wrong options: %s", Error.message);
return NULL;
} // endif Opts
} // endif all
Cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL);
} // endif Pipe
return false;
} // end of MakeCursor
/***********************************************************************/
/* Fetch next document. */
/***********************************************************************/
int CMgoConn::ReadNext(PGLOBAL g)
{
int rc = RC_OK;
if (!Cursor && MakeCursor(g)) {
rc = RC_FX;
} else if (mongoc_cursor_next(Cursor, &Document)) {
if (trace > 1) {
bson_iter_t iter;
ShowDocument(&iter, Document, "");
} else if (trace == 1)
htrc("%s\n", GetDocument(g));
} else if (mongoc_cursor_error(Cursor, &Error)) {
sprintf(g->Message, "Mongo Cursor Failure: %s", Error.message);
rc = RC_FX;
} else
rc = RC_EF;
return rc;
} // end of Fetch
/***********************************************************************/
/* Get the Json string of the current document. */
/***********************************************************************/
PSZ CMgoConn::GetDocument(PGLOBAL g)
{
char *str = bson_as_json(Document, NULL);
PSZ doc = PlugDup(g, str);
bson_free(str);
return doc;
} // end of GetDocument
/***********************************************************************/
/* Use to trace restaurants document contains. */
/***********************************************************************/
void CMgoConn::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
{
if (!doc || bson_iter_init(iter, doc)) {
const char *key;
while (bson_iter_next(iter)) {
key = bson_iter_key(iter);
htrc("Found element key: \"%s\"\n", key);
if (BSON_ITER_HOLDS_UTF8(iter))
htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
else if (BSON_ITER_HOLDS_INT32(iter))
htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
else if (BSON_ITER_HOLDS_INT64(iter))
htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
else if (BSON_ITER_HOLDS_DOUBLE(iter))
htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
else if (BSON_ITER_HOLDS_DATE_TIME(iter))
htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
else if (BSON_ITER_HOLDS_OID(iter)) {
char str[25];
bson_oid_to_string(bson_iter_oid(iter), str);
htrc("%s.%s=%s\n", k, key, str);
} else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
char *str = NULL;
bson_decimal128_t dec;
bson_iter_decimal128(iter, &dec);
bson_decimal128_to_string(&dec, str);
htrc("%s.%s=%s\n", k, key, str);
} else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
bson_iter_t child;
if (bson_iter_recurse(iter, &child))
ShowDocument(&child, NULL, key);
} else if (BSON_ITER_HOLDS_ARRAY(iter)) {
bson_t *arr;
bson_iter_t itar;
const uint8_t *data = NULL;
uint32_t len = 0;
bson_iter_array(iter, &len, &data);
arr = bson_new_from_data(data, len);
ShowDocument(&itar, arr, key);
} // endif's
} // endwhile bson_iter_next
} // endif bson_iter_init
} // end of ShowDocument
/***********************************************************************/
/* Group columns for inserting or updating. */
/***********************************************************************/
void CMgoConn::MakeColumnGroups(PGLOBAL g)
{
Fpc = new(g) INCOL(false);
for (PCOL colp = Pcg->Tdbp->GetColumns(); colp; colp = colp->GetNext())
if (!colp->IsSpecial())
Fpc->AddCol(g, colp, colp->GetJpath(g, false));
} // end of MakeColumnGroups
/***********************************************************************/
/* DocWrite. */
/***********************************************************************/
bool CMgoConn::DocWrite(PGLOBAL g, PINCOL icp)
{
for (PKC kp = icp->Klist; kp; kp = kp->Next)
if (kp->Incolp) {
bool isdoc = !kp->Incolp->Array;
if (isdoc)
BSON_APPEND_DOCUMENT_BEGIN(icp->Child, kp->Key, kp->Incolp->Child);
else
BSON_APPEND_ARRAY_BEGIN(icp->Child, kp->Key, kp->Incolp->Child);
if (DocWrite(g, kp->Incolp))
return true;
if (isdoc)
bson_append_document_end(icp->Child, kp->Incolp->Child);
else
bson_append_array_end(icp->Child, kp->Incolp->Child);
} else if (AddValue(g, kp->Colp, icp->Child, kp->Key, false))
return true;
return false;
} // end of DocWrite
/***********************************************************************/
/* WriteDB: Data Base write routine for DOS access method. */
/***********************************************************************/
int CMgoConn::Write(PGLOBAL g)
{
int rc = RC_OK;
PTDB tp = Pcg->Tdbp;
if (tp->GetMode() == MODE_INSERT) {
Fpc->Init();
if (DocWrite(g, Fpc))
return RC_FX;
if (trace) {
char *str = bson_as_json(Fpc->Child, NULL);
htrc("Inserting: %s\n", str);
bson_free(str);
} // endif trace
if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
Fpc->Child, NULL, &Error)) {
sprintf(g->Message, "Mongo insert: %s", Error.message);
rc = RC_FX;
} // endif insert
} else {
bool b = false;
bson_iter_t iter;
bson_t *query = bson_new();
bson_iter_init(&iter, Document);
if (bson_iter_find(&iter, "_id")) {
if (BSON_ITER_HOLDS_OID(&iter))
b = BSON_APPEND_OID(query, "_id", bson_iter_oid(&iter));
else if (BSON_ITER_HOLDS_INT32(&iter))
b = BSON_APPEND_INT32(query, "_id", bson_iter_int32(&iter));
else if (BSON_ITER_HOLDS_INT64(&iter))
b = BSON_APPEND_INT64(query, "_id", bson_iter_int64(&iter));
else if (BSON_ITER_HOLDS_DOUBLE(&iter))
b = BSON_APPEND_DOUBLE(query, "_id", bson_iter_double(&iter));
else if (BSON_ITER_HOLDS_UTF8(&iter))
b = BSON_APPEND_UTF8(query, "_id", bson_iter_utf8(&iter, NULL));
} // endif iter
if (b) {
if (trace) {
char *str = bson_as_json(query, NULL);
htrc("update query: %s\n", str);
bson_free(str);
} // endif trace
if (tp->GetMode() == MODE_UPDATE) {
bson_t child;
bson_t *update = bson_new();
BSON_APPEND_DOCUMENT_BEGIN(update, "$set", &child);
for (PCOL colp = tp->GetSetCols(); colp; colp = colp->GetNext())
if (AddValue(g, colp, &child, colp->GetJpath(g, false), true))
rc = RC_FX;
bson_append_document_end(update, &child);
if (rc == RC_OK)
if (!mongoc_collection_update(Collection, MONGOC_UPDATE_NONE,
query, update, NULL, &Error)) {
sprintf(g->Message, "Mongo update: %s", Error.message);
rc = RC_FX;
} // endif update
bson_destroy(update);
} else if (!mongoc_collection_remove(Collection,
MONGOC_REMOVE_SINGLE_REMOVE, query, NULL, &Error)) {
sprintf(g->Message, "Mongo delete: %s", Error.message);
rc = RC_FX;
} // endif remove
} else {
strcpy(g->Message, "Mongo update: cannot find _id");
rc = RC_FX;
} // endif b
bson_destroy(query);
} // endif Mode
return rc;
} // end of Write
/***********************************************************************/
/* Remove all documents from the collection. */
/***********************************************************************/
bool CMgoConn::DocDelete(PGLOBAL g)
{
Query = bson_new();
if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE,
Query, NULL, &Error)) {
sprintf(g->Message, "Mongo remove all: %s", Error.message);
return true;
} // endif remove
return false;
} // end of DocDelete
/***********************************************************************/
/* Rewind the collection. */
/***********************************************************************/
void CMgoConn::Rewind(void)
{
mongoc_cursor_t *cursor = mongoc_cursor_clone(Cursor);
mongoc_cursor_destroy(Cursor);
Cursor = cursor;
} // end of Rewind
/***********************************************************************/
/* Table close routine for MONGO tables. */
/***********************************************************************/
void CMgoConn::Close(void)
{
if (Query) bson_destroy(Query);
if (Opts) bson_destroy(Opts);
if (Cursor) mongoc_cursor_destroy(Cursor);
if (Collection) mongoc_collection_destroy(Collection);
if (Client) mongoc_client_pool_push(Pool, Client);
if (Pool) mongoc_client_pool_destroy(Pool);
if (Uri) mongoc_uri_destroy(Uri);
if (Fpc) Fpc->Destroy();
if (fp) fp->Count = 0;
} // end of Close
/***********************************************************************/
/* Mini: used to suppress blanks to json strings. */
/***********************************************************************/
char *CMgoConn::Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b)
{
char *s, *str = NULL;
char *Mbuf = (char*)PlugSubAlloc(g, NULL, colp->GetLength() + 1);
int i, k = 0;
bool ok = true;
if (b)
s = str = bson_array_as_json(bson, NULL);
else
s = str = bson_as_json(bson, NULL);
for (i = 0; i < colp->GetLength() && s[i]; i++) {
switch (s[i]) {
case ' ':
if (ok) continue;
case '"':
ok = !ok;
default:
break;
} // endswitch s[i]
Mbuf[k++] = s[i];
} // endfor i
bson_free(str);
if (i >= colp->GetLength()) {
sprintf(g->Message, "Value too long for column %s", colp->GetName());
throw (int)TYPE_AM_MGO;
} // endif i
Mbuf[k] = 0;
return Mbuf;
} // end of Mini
/***********************************************************************/
/* Retrieve the column value from the document. */
/***********************************************************************/
void CMgoConn::GetColumnValue(PGLOBAL g, PCOL colp)
{
char *jpath = colp->GetJpath(g, false);
PVAL value = colp->GetValue();
if (!strcmp(jpath, "*")) {
value->SetValue_psz(Mini(g, colp, Document, false));
} else if (bson_iter_init(&Iter, Document) &&
bson_iter_find_descendant(&Iter, jpath, &Desc)) {
if (BSON_ITER_HOLDS_UTF8(&Desc))
value->SetValue_psz((PSZ)bson_iter_utf8(&Desc, NULL));
else if (BSON_ITER_HOLDS_INT32(&Desc))
value->SetValue(bson_iter_int32(&Desc));
else if (BSON_ITER_HOLDS_INT64(&Desc))
value->SetValue(bson_iter_int64(&Desc));
else if (BSON_ITER_HOLDS_DOUBLE(&Desc))
value->SetValue(bson_iter_double(&Desc));
else if (BSON_ITER_HOLDS_DATE_TIME(&Desc))
value->SetValue(bson_iter_date_time(&Desc) / 1000);
else if (BSON_ITER_HOLDS_BOOL(&Desc)) {
bool b = bson_iter_bool(&Desc);
if (value->IsTypeNum())
value->SetValue(b ? 1 : 0);
else
value->SetValue_psz(b ? "true" : "false");
} else if (BSON_ITER_HOLDS_OID(&Desc)) {
char str[25];
bson_oid_to_string(bson_iter_oid(&Desc), str);
value->SetValue_psz(str);
} else if (BSON_ITER_HOLDS_NULL(&Iter)) {
// Apparently this does not work...
value->Reset();
value->SetNull(true);
} else if (BSON_ITER_HOLDS_DECIMAL128(&Desc)) {
char *str = NULL;
bson_decimal128_t dec;
bson_iter_decimal128(&Desc, &dec);
bson_decimal128_to_string(&dec, str);
value->SetValue_psz(str);
bson_free(str);
} else if (BSON_ITER_HOLDS_DOCUMENT(&Iter)) {
bson_t *doc;
const uint8_t *data = NULL;
uint32_t len = 0;
bson_iter_document(&Desc, &len, &data);
if (data) {
doc = bson_new_from_data(data, len);
value->SetValue_psz(Mini(g, colp, doc, false));
bson_destroy(doc);
} else {
// ... but we can come here in case of NULL!
value->Reset();
value->SetNull(true);
} // endif data
} else if (BSON_ITER_HOLDS_ARRAY(&Iter)) {
bson_t *arr;
const uint8_t *data = NULL;
uint32_t len = 0;
bson_iter_array(&Desc, &len, &data);
if (data) {
arr = bson_new_from_data(data, len);
value->SetValue_psz(Mini(g, colp, arr, true));
bson_destroy(arr);
} else {
// This is a bug in returning the wrong type
// This fix is only for document items
bson_t *doc;
bson_iter_document(&Desc, &len, &data);
if (data) {
doc = bson_new_from_data(data, len);
value->SetValue_psz(Mini(g, colp, doc, false));
bson_destroy(doc);
} else {
// ... or we can also come here in case of NULL!
value->Reset();
value->SetNull(true);
} // endif data
} // endif data
} else
value->Reset();
} else {
// Field does not exist
value->Reset();
value->SetNull(true);
} // endif Iter
} // end of GetColumnValue
/***********************************************************************/
/* AddValue: Add column value to the document to insert or update. */
/***********************************************************************/
bool CMgoConn::AddValue(PGLOBAL g, PCOL colp, bson_t *doc, char *key, bool upd)
{
bool rc = false;
PVAL value = colp->GetValue();
if (value->IsNull()) {
if (upd)
rc = BSON_APPEND_NULL(doc, key);
else
return false;
} else switch (colp->GetResultType()) {
case TYPE_STRING:
rc = BSON_APPEND_UTF8(doc, key, value->GetCharValue());
break;
case TYPE_INT:
case TYPE_SHORT:
rc = BSON_APPEND_INT32(doc, key, value->GetIntValue());
break;
case TYPE_TINY:
rc = BSON_APPEND_BOOL(doc, key, value->GetIntValue());
break;
case TYPE_BIGINT:
rc = BSON_APPEND_INT64(doc, key, value->GetBigintValue());
break;
case TYPE_DOUBLE:
rc = BSON_APPEND_DOUBLE(doc, key, value->GetFloatValue());
break;
case TYPE_DECIM:
{bson_decimal128_t dec;
if (bson_decimal128_from_string(value->GetCharValue(), &dec))
rc = BSON_APPEND_DECIMAL128(doc, key, &dec);
} break;
case TYPE_DATE:
rc = BSON_APPEND_DATE_TIME(doc, key, value->GetBigintValue() * 1000);
break;
default:
sprintf(g->Message, "Type %d not supported yet", colp->GetResultType());
return true;
} // endswitch Buf_Type
if (!rc) {
strcpy(g->Message, "Adding value failed");
return true;
} else
return false;
} // end of AddValue
#if 0
void *CMgoConn::mgo_alloc(size_t n)
{
char *mst = (char*)PlgDBSubAlloc(G, NULL, n + sizeof(size_t));
if (mst) {
*(size_t*)mst = n;
return mst + sizeof(size_t);
} // endif mst
return NULL;
} // end of mgo_alloc
void *CMgoConn::mgo_calloc(size_t n, size_t sz)
{
void *m = mgo_alloc(n * sz);
if (m)
memset(m, 0, n * sz);
return m;
} // end of mgo_calloc
void *CMgoConn::mgo_realloc(void *m, size_t n)
{
if (!m)
return n ? mgo_alloc(n) : NULL;
size_t *osz = (size_t*)((char*)m - sizeof(size_t));
if (n > *osz) {
void *nwm = mgo_alloc(n);
if (nwm)
memcpy(nwm, m, *osz);
return nwm;
} else {
*osz = n;
return m;
} // endif n
} // end of mgo_realloc
#endif // 0

115
storage/connect/cmgoconn.h Normal file
View File

@@ -0,0 +1,115 @@
/***********************************************************************/
/* CMgoConn.h : header file for the MongoDB connection classes. */
/***********************************************************************/
/***********************************************************************/
/* Include MongoDB library header files. */
/***********************************************************************/
#include <bson.h>
#include <bcon.h>
#include <mongoc.h>
// C connection to a MongoDB data source
class TDBCMG;
class MGOCOL;
/***********************************************************************/
/* Include MongoDB library header files. */
/***********************************************************************/
typedef class INCOL *PINCOL;
typedef class MGODEF *PMGODEF;
typedef class TDBCMG *PTDBCMG;
typedef class MGOCOL *PMGOCOL;
typedef struct mongo_parms {
PTDB Tdbp;
PCSZ Uristr; // Driver URI
PCSZ Db_name;
PCSZ Coll_name;
PCSZ Options;
PCSZ Filter;
bool Pipe;
//PCSZ User; // User connect info
//PCSZ Pwd; // Password connect info
//int Fsize; // Fetch size
//bool Scrollable; // Scrollable cursor
} CMGOPARM, *PCPARM;
typedef struct KEYCOL {
KEYCOL *Next;
PINCOL Incolp;
PCOL Colp;
char *Key;
} *PKC;
/***********************************************************************/
/* Used when inserting values in a MongoDB collection. */
/***********************************************************************/
class INCOL : public BLOCK {
public:
// Constructor
INCOL(bool ar) { Child = bson_new(); Klist = NULL; Array = ar; }
// Methods
void AddCol(PGLOBAL g, PCOL colp, char *jp);
void Init(void);
void Destroy(void);
//Members
bson_t *Child;
PKC Klist;
bool Array;
}; // end of INCOL;
/***********************************************************************/
/* CMgoConn class. */
/***********************************************************************/
class CMgoConn : public BLOCK {
friend class TDBCMG;
friend class CMGDISC;
public:
// Constructor
CMgoConn(PGLOBAL g, PCPARM pcg);
//static void *mgo_alloc(size_t n);
//static void *mgo_calloc(size_t n, size_t sz);
//static void *mgo_realloc(void *m, size_t n);
//static void mgo_free(void *) {}
// Implementation
bool IsConnected(void) { return m_Connected; }
bool Connect(PGLOBAL g);
int CollSize(PGLOBAL g);
bool MakeCursor(PGLOBAL g);
int ReadNext(PGLOBAL g);
PSZ GetDocument(PGLOBAL g);
void ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k);
void MakeColumnGroups(PGLOBAL g);
bool DocWrite(PGLOBAL g, PINCOL icp);
int Write(PGLOBAL g);
bool DocDelete(PGLOBAL g);
void Rewind(void);
void Close(void);
PSZ Mini(PGLOBAL g, PCOL colp, const bson_t *bson, bool b);
void GetColumnValue(PGLOBAL g, PCOL colp);
bool AddValue(PGLOBAL g, PCOL colp, bson_t *doc, char *key, bool upd);
protected:
// Members
PCPARM Pcg;
mongoc_uri_t *Uri;
mongoc_client_pool_t *Pool; // Thread safe client pool
mongoc_client_t *Client; // The MongoDB client
mongoc_database_t *Database; // The MongoDB database
mongoc_collection_t *Collection; // The MongoDB collection
mongoc_cursor_t *Cursor;
const bson_t *Document;
bson_t *Query; // MongoDB cursor filter
bson_t *Opts; // MongoDB cursor options
bson_error_t Error;
bson_iter_t Iter; // Used to retrieve column value
bson_iter_t Desc; // Descendant iter
PINCOL Fpc; // To insert INCOL classes
PFBLOCK fp;
bool m_Connected;
}; // end of class CMgoConn

View File

@@ -197,7 +197,7 @@ int COLBLK::GetLengthEx(void)
void COLBLK::ReadColumn(PGLOBAL g)
{
sprintf(g->Message, MSG(UNDEFINED_AM), "ReadColumn");
throw TYPE_COLBLK;
throw (int)TYPE_COLBLK;
} // end of ReadColumn
/***********************************************************************/
@@ -208,7 +208,7 @@ void COLBLK::ReadColumn(PGLOBAL g)
void COLBLK::WriteColumn(PGLOBAL g)
{
sprintf(g->Message, MSG(UNDEFINED_AM), "WriteColumn");
throw TYPE_COLBLK;
throw (int)TYPE_COLBLK;
} // end of WriteColumn
/***********************************************************************/
@@ -262,7 +262,7 @@ SPCBLK::SPCBLK(PCOLUMN cp)
void SPCBLK::WriteColumn(PGLOBAL g)
{
sprintf(g->Message, MSG(SPCOL_READONLY), Name);
throw TYPE_COLBLK;
throw (int)TYPE_COLBLK;
} // end of WriteColumn
/***********************************************************************/

View File

@@ -38,7 +38,8 @@ class DllExport COLBLK : public XOBJECT {
virtual PTDB GetTo_Tdb(void) {return To_Tdb;}
virtual int GetClustered(void) {return 0;}
virtual int IsClustered(void) {return FALSE;}
PCOL GetNext(void) {return Next;}
virtual PSZ GetJpath(PGLOBAL g, bool proj) {return NULL;}
PCOL GetNext(void) {return Next;}
PSZ GetName(void) {return Name;}
int GetIndex(void) {return Index;}
ushort GetColUse(void) {return ColUse;}

View File

@@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2017
/* Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -66,8 +66,10 @@ PGLOBAL CntExit(PGLOBAL g)
if (g) {
CntEndDB(g);
if (g->Activityp)
delete g->Activityp;
if (g->Activityp) {
delete g->Activityp;
g->Activityp = NULL;
} // endif Activityp
PlugExit(g);
g= NULL;
@@ -80,7 +82,7 @@ PGLOBAL CntExit(PGLOBAL g)
/* CntEndDB: DB termination semantic routine. */
/***********************************************************************/
void CntEndDB(PGLOBAL g)
{
{
PDBUSER dbuserp= PlgGetUser(g);
if (dbuserp) {
@@ -88,9 +90,14 @@ void CntEndDB(PGLOBAL g)
delete dbuserp->Catalog;
free(dbuserp);
} // endif dbuserp
} // end of CntEndDB
if (trace)
htrc("CntEndDB: Freeing Dup\n");
g->Activityp->Aptr = NULL;
} // endif dbuserp
} // end of CntEndDB
/***********************************************************************/
/* CntCheckDB: Initialize a DB application session. */
@@ -185,10 +192,10 @@ bool CntInfo(PGLOBAL g, PTDB tp, PXF info)
/***********************************************************************/
PTDB CntGetTDB(PGLOBAL g, LPCSTR name, MODE mode, PHC h)
{
PTDB tdbp;
PTDB tdbp = NULL;
PTABLE tabp;
PDBUSER dup = PlgGetUser(g);
volatile PCATLG cat = (dup) ? dup->Catalog : NULL; // Safe over longjmp
volatile PCATLG cat = (dup) ? dup->Catalog : NULL; // Safe over throw
if (trace)
printf("CntGetTDB: name=%s mode=%d cat=%p\n", name, mode, cat);

View File

@@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2011
/* Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,6 +15,7 @@
/**************** Cnt H Declares Source Code File (.H) *****************/
/* Name: CONNECT.H Version 2.4 */
/* Author Olivier BERTRAND bertrandop@gmail.com */
/* This file contains the some based classes declares. */
/***********************************************************************/
#include "filamtxt.h"

View File

@@ -1,3 +1,4 @@
/* Copyright (C) MariaDB Corporation Ab */
#define MSG_ACCESS_VIOLATN "Access violation"
#define MSG_ADD_BAD_TYPE "Array add value type mismatch (%s -> %s)"
#define MSG_ALLOC_ERROR "Error allocating %s"

View File

@@ -290,6 +290,9 @@ void ZIPUTIL::close()
zipfile = NULL;
} // endif zipfile
if (fp)
fp->Count = 0;
} // end of close
/***********************************************************************/
@@ -493,6 +496,9 @@ void UNZIPUTL::close()
zipfile = NULL;
} // endif zipfile
if (fp)
fp->Count = 0;
} // end of close
/***********************************************************************/

View File

@@ -33,18 +33,11 @@
#include "tabcol.h"
#include "xtable.h"
#include "array.h"
//#include "subquery.h"
#include "filter.h"
//#include "token.h"
//#include "select.h"
#include "xindex.h"
#if defined(MONGO_SUPPORT)
#include "filamtxt.h"
#include "tabdos.h"
#include "tabjson.h"
#if defined(MONGO_SUPPORT) || defined(JDBC_SUPPORT)
#include "tabext.h"
#include "tabmgo.h"
#endif // MONGO_SUPPORT
#endif // MONGO_SUPPORT || JDBC_SUPPORT
/***********************************************************************/
/* Utility routines. */
@@ -94,7 +87,7 @@ BYTE OpBmp(PGLOBAL g, OPVAL opc)
case OP_EXIST: bt = 0x00; break;
default:
sprintf(g->Message, MSG(BAD_FILTER_OP), opc);
throw TYPE_ARRAY;
throw (int)TYPE_ARRAY;
} // endswitch opc
return bt;
@@ -1412,11 +1405,11 @@ PFIL FILTER::Copy(PTABS t)
} // end of Copy
#endif // 0
#if defined(MONGO_SUPPORT)
/***********************************************************************/
/* Make selector json representation for Mongo tables. */
/***********************************************************************/
#if defined(MONGO_SUPPORT)
bool FILTER::MakeSelector(PGLOBAL g, PSTRG s, bool m)
bool FILTER::MakeSelector(PGLOBAL g, PSTRG s)
{
s->Append('{');
@@ -1428,29 +1421,21 @@ bool FILTER::MakeSelector(PGLOBAL g, PSTRG s, bool m)
s->Append(Opc == OP_AND ? "and" : "or");
s->Append("\":[");
if (((PFIL)Arg(0))->MakeSelector(g, s, m))
if (((PFIL)Arg(0))->MakeSelector(g, s))
return true;
s->Append(',');
if (((PFIL)Arg(1))->MakeSelector(g, s, m))
if (((PFIL)Arg(1))->MakeSelector(g, s))
return true;
s->Append(']');
} else {
char *pth, buf[501];
if (GetArgType(0) != TYPE_COLBLK)
return true;
s->Append('"');
if (m)
pth = ((PMGOCOL)Arg(0))->Jpath;
else if (!(pth = ((PJCOL)Arg(0))->GetJpath(g, false)))
return true;
s->Append(pth);
s->Append(((PCOL)Arg(0))->GetJpath(g, false));
s->Append("\":{\"$");
switch (Opc) {
@@ -1472,26 +1457,26 @@ bool FILTER::MakeSelector(PGLOBAL g, PSTRG s, bool m)
case OP_LE:
s->Append("lte");
break;
//case OP_NULL:
// s->Append("ne");
// break;
//case OP_LIKE:
// s->Append("ne");
// break;
//case OP_EXIST:
// s->Append("ne");
// break;
case OP_NULL:
case OP_LIKE:
case OP_EXIST:
default:
return true;
} // endswitch Opc
s->Append("\":");
if (GetArgType(1) == TYPE_COLBLK)
return true;
if (GetArgType(1) == TYPE_COLBLK) {
s->Append("\"$");
s->Append(((PEXTCOL)Arg(1))->GetJpath(g, false));
s->Append('"');
} else {
char buf[501];
Arg(1)->Prints(g, buf, 500);
s->Append(buf);
} // endif Type
Arg(1)->Prints(g, buf, 500);
s->Append(buf);
s->Append('}');
} // endif Opc
@@ -1804,7 +1789,7 @@ PFIL PrepareFilter(PGLOBAL g, PFIL fp, bool having)
break; // Remove eventual ending separator(s)
// if (fp->Convert(g, having))
// throw TYPE_ARRAY;
// (int)throw TYPE_ARRAY;
filp = fp;
fp = fp->Next;
@@ -1837,7 +1822,7 @@ DllExport bool ApplyFilter(PGLOBAL g, PFIL filp)
// return TRUE;
if (filp->Eval(g))
throw TYPE_FILTER;
throw (int)TYPE_FILTER;
if (trace > 1)
htrc("PlugFilter filp=%p result=%d\n",

View File

@@ -1,7 +1,7 @@
/*************** Filter H Declares Source Code File (.H) ***************/
/* Name: FILTER.H Version 1.2 */
/* Name: FILTER.H Version 1.3 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2010-2015 */
/* (C) Copyright to the author Olivier BERTRAND 2010-2017 */
/* */
/* This file contains the FILTER and derived classes declares. */
/***********************************************************************/
@@ -62,7 +62,7 @@ class DllExport FILTER : public XOBJECT { /* Filter description block */
//virtual bool CheckLocal(PTDB);
//virtual int CheckSpcCol(PTDB tdbp, int n);
#if defined(MONGO_SUPPORT)
bool MakeSelector(PGLOBAL g, PSTRG s, bool m);
bool MakeSelector(PGLOBAL g, PSTRG s);
#endif // MONGO_SUPPORT
virtual void Printf(PGLOBAL g, FILE *f, uint n);
virtual void Prints(PGLOBAL g, char *ps, uint z);

View File

@@ -1,6 +1,7 @@
/***********************************************************************/
/* GLOBAL.H: Declaration file used by all CONNECT implementations. */
/* (C) Copyright Olivier Bertrand 1993-2017 */
/* (C) Copyright MariaDB Corporation Ab */
/* Author Olivier Bertrand 1993-2017 */
/***********************************************************************/
/***********************************************************************/
@@ -57,31 +58,10 @@
/* Miscellaneous Constants */
/***********************************************************************/
#define NO_IVAL -95684275 /* Used by GetIntegerOption */
#define VMLANG 370 /* Size of olf VM lang blocks */
#define MAX_JUMP 24 /* Maximum jump level number */
#define MAX_STR 4160 /* Maximum message length */
#define STR_SIZE 501 /* Length of char strings. */
#define STD_INPUT 0 /* Standard language input */
#define STD_OUTPUT 1 /* Standard language output */
#define ERROR_OUTPUT 2 /* Error message output */
#define DEBUG_OUTPUT 3 /* Debug info output */
#define PROMPT_OUTPUT 4 /* Prompt message output */
#define COPY_OUTPUT 5 /* Copy of language input */
#define STD_MSG 6 /* System message file */
#define DEBUG_MSG 7 /* Debug message file */
#define DUMMY 0 /* Dummy file index in Ldm block */
#define STDIN 1 /* stdin file index in Ldm block */
#define STDOUT 2 /* stdout file index in Ldm block */
#define STDERR 3 /* stderr file index in Ldm block */
#define STDEBUG 4 /* debug file index in Ldm block */
#define STDPRN 5 /* stdprn file index in Ldm block */
#define STDFREE 6 /* Free file index in Ldm block */
#define TYPE_SEM -2 /* Returned semantic function */
#define TYPE_DFONC -2 /* Indirect sem ref in FPARM */
#define TYPE_VOID -1
#define TYPE_SBPAR -1 /* Phrase reference in FPARM */
#define TYPE_SEMX 0 /* Initial semantic function type? */
#define TYPE_ERROR 0
#define TYPE_STRING 1
#define TYPE_DOUBLE 2
@@ -95,22 +75,6 @@
#define TYPE_BIN 10
#define TYPE_PCHAR 11
#if defined(OS32)
#define SYS_STAMP "OS32"
#elif defined(UNIX) || defined(LINUX) || defined(UNIV_LINUX)
#define SYS_STAMP "UNIX"
#elif defined(OS16)
#define SYS_STAMP "OS16"
#elif defined(DOSR)
#define SYS_STAMP "DOSR"
#elif defined(WIN)
#define SYS_STAMP "WIN1"
#elif defined(__WIN__)
#define SYS_STAMP "WIN2"
#else
#define SYS_STAMP "XXXX"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
@@ -118,11 +82,6 @@ extern "C" {
/***********************************************************************/
/* Static variables */
/***********************************************************************/
#if defined(STORAGE)
char sys_stamp[5] = SYS_STAMP;
#else
extern char sys_stamp[];
#endif
/***********************************************************************/
/* File-Selection Indicators */

View File

@@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2017
/* Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -98,8 +98,7 @@
rnd_next signals that it has reached the end of its data. Calls to
ha_connect::extra() are hints as to what will be occuring to the request.
Happy use!<br>
-Olivier
Author Olivier Bertrand
*/
#ifdef USE_PRAGMA_IMPLEMENTATION
@@ -181,6 +180,10 @@ extern "C" {
#endif // !__WIN__
} // extern "C"
#if defined(NEW_MAR)
#define stored_in_db stored_in_db()
#endif // NEW_MAR)
#if defined(XMAP)
my_bool xmap= false;
#endif // XMAP
@@ -198,21 +201,19 @@ extern "C" {
char *ClassPath;
#endif // JDBC_SUPPORT
#if defined(__WIN__)
CRITICAL_SECTION parsec; // Used calling the Flex parser
#else // !__WIN__
pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER;
#endif // !__WIN__
pthread_mutex_t parmut;
pthread_mutex_t usrmut;
pthread_mutex_t tblmut;
/***********************************************************************/
/* Utility functions. */
/***********************************************************************/
PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info);
PQRYRES VirColumns(PGLOBAL g, bool info);
PQRYRES JSONColumns(PGLOBAL g, char *db, char *dsn, PTOS topt, bool info);
PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info);
#if defined(MONGO_SUPPORT)
PQRYRES MGOColumns(PGLOBAL g, char *db, PTOS topt, bool info);
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ url, PTOS topt, bool info);
#endif // MONGO_SUPPORT
int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v);
void PushWarning(PGLOBAL g, THD *thd, int level);
@@ -220,10 +221,13 @@ bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, PCSZ host, PCSZ db,
PCSZ tab, PCSZ src, int port);
bool ZipLoadFile(PGLOBAL, PCSZ, PCSZ, PCSZ, bool, bool);
bool ExactInfo(void);
#if defined(CMGO_SUPPORT)
void mongo_init(bool);
#endif // CMGO_SUPPORT
USETEMP UseTemp(void);
int GetConvSize(void);
TYPCONV GetTypeConv(void);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
char *GetJavaWrapper(void);
uint GetWorkSize(void);
@@ -333,6 +337,13 @@ static MYSQL_THDVAR_ENUM(
0, // def (no)
&xconv_typelib); // typelib
// Null representation for JSON values
static MYSQL_THDVAR_STR(json_null,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"Representation of Json null values",
// check_json_null, update_json_null,
NULL, NULL, "<null>");
// Estimate max number of rows for JSON aggregate functions
static MYSQL_THDVAR_UINT(json_grp_size,
PLUGIN_VAR_RQCMDARG, // opt
@@ -344,7 +355,7 @@ static MYSQL_THDVAR_UINT(json_grp_size,
static MYSQL_THDVAR_STR(java_wrapper,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"Java wrapper class name",
// check_class_path, update_class_path,
// check_java_wrapper, update_java_wrapper,
NULL, NULL, "wrappers/JdbcInterface");
#endif // JDBC_SUPPORT
@@ -384,6 +395,8 @@ bool ExactInfo(void) {return THDVAR(current_thd, exact_info);}
USETEMP UseTemp(void) {return (USETEMP)THDVAR(current_thd, use_tempfile);}
int GetConvSize(void) {return THDVAR(current_thd, conv_size);}
TYPCONV GetTypeConv(void) {return (TYPCONV)THDVAR(current_thd, type_conv);}
char *GetJsonNull(void)
{return connect_hton ? THDVAR(current_thd, json_null) : NULL;}
uint GetJsonGrpSize(void)
{return connect_hton ? THDVAR(current_thd, json_grp_size) : 10;}
uint GetWorkSize(void) {return THDVAR(current_thd, work_size);}
@@ -670,18 +683,20 @@ static int connect_init_func(void *p)
#if defined(__WIN__)
sql_print_information("CONNECT: %s", compver);
InitializeCriticalSection((LPCRITICAL_SECTION)&parsec);
#else // !__WIN__
sql_print_information("CONNECT: %s", version);
#endif // !__WIN__
pthread_mutex_init(&parmut, NULL);
pthread_mutex_init(&usrmut, NULL);
pthread_mutex_init(&tblmut, NULL);
#if defined(LIBXML2_SUPPORT)
XmlInitParserLib();
#endif // LIBXML2_SUPPORT
#if defined(MONGO_SUPPORT)
#if defined(CMGO_SUPPORT)
mongo_init(true);
#endif // MONGO_SUPPORT
#endif // CMGO_SUPPORT
init_connect_psi_keys();
@@ -701,7 +716,7 @@ static int connect_init_func(void *p)
DTVAL::SetTimeShift(); // Initialize time zone shift once for all
BINCOL::SetEndian(); // Initialize host endian setting
#if defined(JDBC_SUPPORT)
JDBConn::SetJVM();
JAVAConn::SetJVM();
#endif // JDBC_SUPPORT
DBUG_RETURN(0);
} // end of connect_init_func
@@ -721,21 +736,20 @@ static int connect_done_func(void *)
XmlCleanupParserLib();
#endif // LIBXML2_SUPPORT
#if defined(MONGO_SUPPORT)
#if defined(CMGO_SUPPORT)
mongo_init(false);
#endif // MONGO_SUPPORT
#endif // CMGO_SUPPORT
#ifdef JDBC_SUPPORT
JDBConn::ResetJVM();
JAVAConn::ResetJVM();
#endif // JDBC_SUPPORT
#if defined(__WIN__)
DeleteCriticalSection((LPCRITICAL_SECTION)&parsec);
#else // !__WIN__
#if !defined(__WIN__)
PROFILE_End();
#endif // !__WIN__
for (pc= user_connect::to_users; pc; pc= pn) {
pthread_mutex_lock(&usrmut);
for (pc= user_connect::to_users; pc; pc= pn) {
if (pc->g)
PlugCleanup(pc->g, true);
@@ -743,6 +757,11 @@ static int connect_done_func(void *)
delete pc;
} // endfor pc
pthread_mutex_unlock(&usrmut);
pthread_mutex_destroy(&usrmut);
pthread_mutex_destroy(&parmut);
pthread_mutex_destroy(&tblmut);
connect_hton= NULL;
DBUG_RETURN(error);
} // end of connect_done_func
@@ -855,6 +874,7 @@ ha_connect::~ha_connect(void)
static void PopUser(PCONNECT xp)
{
if (xp) {
pthread_mutex_lock(&usrmut);
xp->count--;
if (!xp->count) {
@@ -879,6 +899,7 @@ static void PopUser(PCONNECT xp)
delete xp;
} // endif count
pthread_mutex_unlock(&usrmut);
} // endif xp
} // end of PopUser
@@ -892,23 +913,36 @@ static PCONNECT GetUser(THD *thd, PCONNECT xp)
if (!thd)
return NULL;
if (xp && thd == xp->thdp)
return xp;
if (xp) {
if (thd == xp->thdp)
return xp;
for (xp= user_connect::to_users; xp; xp= xp->next)
PopUser(xp); // Avoid memory leak
} // endif xp
pthread_mutex_lock(&usrmut);
for (xp= user_connect::to_users; xp; xp= xp->next)
if (thd == xp->thdp)
break;
if (!xp) {
xp= new user_connect(thd);
if (xp)
xp->count++;
if (xp->user_init()) {
delete xp;
xp= NULL;
} // endif user_init
pthread_mutex_unlock(&usrmut);
} else
xp->count++;
if (!xp) {
xp = new user_connect(thd);
if (xp->user_init()) {
delete xp;
xp = NULL;
} // endif user_init
} // endif xp
//} else
// xp->count++;
return xp;
} // end of GetUser
@@ -1037,26 +1071,43 @@ PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
return (char*)def;
char key[16], val[256];
char *pk, *pv, *pn;
char *pv, *pn, *pk= (char*)oplist;
PCSZ opval= def;
int n;
for (pk= (char*)oplist; pk; pk= ++pn) {
while (*pk == ' ')
pk++;
for (; pk; pk= pn) {
pn= strchr(pk, ',');
pv= strchr(pk, '=');
if (pv && (!pn || pv < pn)) {
n = MY_MIN(static_cast<size_t>(pv - pk), sizeof(key) - 1);
memcpy(key, pk, n);
while (n && key[n - 1] == ' ')
n--;
key[n]= 0;
pv++;
while(*(++pv) == ' ') ;
n= MY_MIN((pn ? pn - pv : strlen(pv)), sizeof(val) - 1);
memcpy(val, pv, n);
val[n]= 0;
while (n && val[n - 1] == ' ')
n--;
val[n]= 0;
} else {
n= MY_MIN((pn ? pn - pk : strlen(pk)), sizeof(key) - 1);
memcpy(key, pk, n);
key[n]= 0;
while (n && key[n - 1] == ' ')
n--;
key[n]= 0;
val[0]= 0;
} // endif pv
@@ -1066,6 +1117,7 @@ PCSZ GetListOption(PGLOBAL g, PCSZ opname, PCSZ oplist, PCSZ def)
} else if (!pn)
break;
while (*(++pn) == ' ') ;
} // endfor pk
return opval;
@@ -1441,7 +1493,7 @@ void *ha_connect::GetColumnOption(PGLOBAL g, void *field, PCOLINFO pcf)
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
pcf->Flags |= U_VAR;
/* no break */
// fall through
default:
pcf->Type= MYSQLtoPLG(fp->type(), &v);
break;
@@ -2560,7 +2612,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond)
case Item_func::LE_FUNC: vop= OP_LE; break;
case Item_func::GE_FUNC: vop= OP_GE; break;
case Item_func::GT_FUNC: vop= OP_GT; break;
case Item_func::IN_FUNC: vop= OP_IN;
case Item_func::IN_FUNC: vop= OP_IN; /* fall through */
case Item_func::BETWEEN:
ismul= true;
neg= ((Item_func_opt_neg *)condf)->negated;
@@ -2816,8 +2868,9 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
case Item_func::LIKE_FUNC: vop= OP_LIKE; break;
case Item_func::ISNOTNULL_FUNC:
neg = true;
// fall through
case Item_func::ISNULL_FUNC: vop= OP_NULL; break;
case Item_func::IN_FUNC: vop= OP_IN;
case Item_func::IN_FUNC: vop= OP_IN; /* fall through */
case Item_func::BETWEEN:
ismul= true;
neg= ((Item_func_opt_neg *)condf)->negated;
@@ -2944,6 +2997,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
break;
} // endif ODBC
// fall through
case MYSQL_TYPE_DATE:
if (tty == TYPE_AM_ODBC) {
strcat(s, "{d '");
@@ -4081,7 +4135,7 @@ int ha_connect::info(uint flag)
if (xmod == MODE_ANY || xmod == MODE_ALTER) {
// Pure info, not a query
pure= true;
xp->CheckCleanup();
xp->CheckCleanup(xmod == MODE_ANY && valid_query_id == 0);
} // endif xmod
// This is necessary for getting file length
@@ -4094,8 +4148,10 @@ int ha_connect::info(uint flag)
} else
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
if (!(tdbp= GetTDB(g)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR); // Should never happen
if (!(tdbp = GetTDB(g))) {
my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0));
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif tdbp
valid_info = false;
} // endif tdbp
@@ -4342,7 +4398,11 @@ bool ha_connect::IsSameIndex(PIXDEF xp1, PIXDEF xp2)
MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
MODE newmode, bool *chk, bool *cras)
{
#if defined(DEVELOPMENT)
if (true) {
#else
if (trace) {
#endif
LEX_STRING *query_string= thd_query_string(thd);
htrc("%p check_mode: cmdtype=%d\n", this, thd_sql_command(thd));
htrc("Cmd=%.*s\n", (int) query_string->length, query_string->str);
@@ -4354,7 +4414,7 @@ MODE ha_connect::CheckMode(PGLOBAL g, THD *thd,
if (newmode == MODE_WRITE) {
switch (thd_sql_command(thd)) {
case SQLCOM_LOCK_TABLES:
locked= 2;
locked= 2; // fall through
case SQLCOM_CREATE_TABLE:
case SQLCOM_INSERT:
case SQLCOM_LOAD:
@@ -5299,16 +5359,17 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#if defined(ODBC_SUPPORT)
POPARM sop= NULL;
PCSZ ucnc= NULL;
bool cnc= false;
PCSZ tabtyp = NULL;
bool cnc= false;
int cto= -1, qto= -1;
#endif // ODBC_SUPPORT
#if defined(JDBC_SUPPORT) || defined(MONGO_SUPPORT)
#if defined(JDBC_SUPPORT)
PJPARM sjp= NULL;
#endif // JDBC_SUPPORT
PCSZ driver= NULL;
char *url= NULL;
//char *prop= NULL;
PCSZ tabtyp= NULL;
#endif // JDBC_SUPPORT
#endif // JDBC_SUPPORT || MONGO_SUPPORT
uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL);
bool bif, ok= false, dbf= false;
TABTYPE ttp= TAB_UNDEF;
@@ -5316,6 +5377,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
PCOLRES crp;
PCONNECT xp= NULL;
PGLOBAL g= GetPlug(thd, xp);
if (!g)
return HA_ERR_INTERNAL_ERROR;
PDBUSER dup= PlgGetUser(g);
PCATLG cat= (dup) ? dup->Catalog : NULL;
PTOS topt= table_s->option_struct;
@@ -5323,10 +5388,6 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
String sql(buf, sizeof(buf), system_charset_info);
sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info);
if (!g)
return HA_ERR_INTERNAL_ERROR;
user= host= pwd= tbl= src= col= ocl= pic= fcl= skc= rnk= zfn= dsn= NULL;
// Get the useful create options
@@ -5361,19 +5422,17 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
#endif // __WIN__
port= atoi(GetListOption(g, "port", topt->oplist, "0"));
#if defined(ODBC_SUPPORT)
mxr= atoi(GetListOption(g,"maxres", topt->oplist, "0"));
tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
mxr= atoi(GetListOption(g,"maxres", topt->oplist, "0"));
cto= atoi(GetListOption(g,"ConnectTimeout", topt->oplist, "-1"));
qto= atoi(GetListOption(g,"QueryTimeout", topt->oplist, "-1"));
if ((ucnc= GetListOption(g, "UseDSN", topt->oplist)))
cnc= (!*ucnc || *ucnc == 'y' || *ucnc == 'Y' || atoi(ucnc) != 0);
#endif
#if defined(JDBC_SUPPORT)
#if defined(JDBC_SUPPORT) || defined(MONGO_SUPPORT)
driver= GetListOption(g, "Driver", topt->oplist, NULL);
// url= GetListOption(g, "URL", topt->oplist, NULL);
// prop = GetListOption(g, "Properties", topt->oplist, NULL);
tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL);
#endif // JDBC_SUPPORT
#endif // JDBC_SUPPORT || MONGO_SUPPORT
#if defined(PROMPT_OK)
cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0"));
#endif // PROMPT_OK
@@ -5733,11 +5792,14 @@ static int connect_assisted_discovery(handlerton *, THD* thd,
qrp = VirColumns(g, fnc == FNC_COL);
break;
case TAB_JSON:
qrp = JSONColumns(g, (char*)db, dsn, topt, fnc == FNC_COL);
qrp = JSONColumns(g, db, dsn, topt, fnc == FNC_COL);
break;
#if defined(MONGO_SUPPORT)
case TAB_MONGO:
qrp = MGOColumns(g, (char*)db, topt, fnc == FNC_COL);
if (!(url = strz(g, create_info->connect_string)) || !*url)
url = "mongodb://localhost:27017";
qrp = MGOColumns(g, db, url, topt, fnc == FNC_COL);
break;
#endif // MONGO_SUPPORT
#if defined(LIBXML2_SUPPORT) || defined(DOMDOC_SUPPORT)
@@ -6055,6 +6117,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
TABTYPE type;
TABLE *st= table; // Probably unuseful
THD *thd= ha_thd();
LEX_STRING cnc = table_arg->s->connect_string;
#if defined(WITH_PARTITION_STORAGE_ENGINE)
partition_info *part_info= table_arg->part_info;
#endif // WITH_PARTITION_STORAGE_ENGINE
@@ -6102,7 +6165,8 @@ int ha_connect::create(const char *name, TABLE *table_arg,
if (check_privileges(thd, options, GetDBfromName(name)))
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
inward= IsFileType(type) && !options->filename;
inward= IsFileType(type) && !options->filename &&
(type != TAB_JSON || !cnc.length);
if (options->data_charset) {
const CHARSET_INFO *data_charset;
@@ -6155,6 +6219,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif tabname
// fall through
case TAB_MYSQL:
#if defined(WITH_PARTITION_STORAGE_ENGINE)
if (!part_info)
@@ -6199,7 +6264,7 @@ int ha_connect::create(const char *name, TABLE *table_arg,
DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
} // endif CheckSelf
}break;
} break;
default: /* do nothing */;
break;
} // endswitch ttp
@@ -6645,7 +6710,7 @@ bool ha_connect::FileExists(const char *fn, bool bf)
} // end of FileExists
// Called by SameString and NoFieldOptionChange
bool ha_connect::CheckString(const char *str1, const char *str2)
bool ha_connect::CheckString(PCSZ str1, PCSZ str2)
{
bool b1= (!str1 || !*str1), b2= (!str2 || !*str2);
@@ -7093,6 +7158,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= {
#if defined(XMSG)
MYSQL_SYSVAR(errmsg_dir_path),
#endif // XMSG
MYSQL_SYSVAR(json_null),
MYSQL_SYSVAR(json_grp_size),
#if defined(JDBC_SUPPORT)
MYSQL_SYSVAR(jvm_path),

View File

@@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2015
/* Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -14,6 +14,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/** @file ha_connect.h
Author Olivier Bertrand
@brief
The ha_connect engine is a prototype storage engine to access external data.
@@ -165,8 +166,8 @@ public:
~ha_connect();
// CONNECT Implementation
static bool connect_init(void);
static bool connect_end(void);
//static bool connect_init(void);
//static bool connect_end(void);
TABTYPE GetRealType(PTOS pos= NULL);
char *GetRealString(PCSZ s);
PCSZ GetStringOption(PCSZ opname, PCSZ sdef= NULL);

View File

@@ -0,0 +1,621 @@
/************ Javaconn C++ Functions Source Code File (.CPP) ***********/
/* Name: JAVAConn.CPP Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the JAVA connection classes functions. */
/***********************************************************************/
#if defined(__WIN__)
// This is needed for RegGetValue
#define _WINVER 0x0601
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif // __WIN__
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
#include <m_string.h>
#if defined(__WIN__)
#include <direct.h> // for getcwd
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
#else // !__WIN__
#if defined(UNIX)
#include <errno.h>
#else // !UNIX
#endif // !UNIX
#include <stdio.h>
#include <stdlib.h> // for getenv
#define NODW
#endif // !__WIN__
/***********************************************************************/
/* Required objects includes. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "colblk.h"
#include "xobject.h"
#include "xtable.h"
#include "tabext.h"
#include "javaconn.h"
#include "resource.h"
#include "valblk.h"
#include "osutil.h"
#if defined(__WIN__)
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // __WIN__
#define nullptr 0
//TYPCONV GetTypeConv();
//int GetConvSize();
extern char *JvmPath; // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_path global variable value
char *GetJavaWrapper(void); // The connect_java_wrapper variable value
/***********************************************************************/
/* Static JAVAConn objects. */
/***********************************************************************/
void *JAVAConn::LibJvm = NULL;
CRTJVM JAVAConn::CreateJavaVM = NULL;
GETJVM JAVAConn::GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GETDEF JAVAConn::GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
/***********************************************************************/
/* Some macro's (should be defined elsewhere to be more accessible) */
/***********************************************************************/
#if defined(_DEBUG)
#define ASSERT(f) assert(f)
#define DEBUG_ONLY(f) (f)
#else // !_DEBUG
#define ASSERT(f) ((void)0)
#define DEBUG_ONLY(f) ((void)0)
#endif // !_DEBUG
/***********************************************************************/
/* Allocate the structure used to refer to the result set. */
/***********************************************************************/
static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, PCSZ db,
PCSZ tab, PQRYRES qrp)
{
JCATPARM *cap;
#if defined(_DEBUG)
assert(qrp);
#endif
if ((cap = (JCATPARM *)PlgDBSubAlloc(g, NULL, sizeof(JCATPARM)))) {
memset(cap, 0, sizeof(JCATPARM));
cap->Id = fid;
cap->Qrp = qrp;
cap->DB = db;
cap->Tab = tab;
} // endif cap
return cap;
} // end of AllocCatInfo
/***********************************************************************/
/* JAVAConn construction/destruction. */
/***********************************************************************/
JAVAConn::JAVAConn(PGLOBAL g, PCSZ wrapper)
{
m_G = g;
jvm = nullptr; // Pointer to the JVM (Java Virtual Machine)
env = nullptr; // Pointer to native interface
jdi = nullptr; // Pointer to the java wrapper class
job = nullptr; // The java wrapper class object
errid = nullptr;
DiscFunc = "Disconnect";
Msg = NULL;
m_Wrap = (wrapper) ? wrapper : GetJavaWrapper();
if (!strchr(m_Wrap, '/')) {
// Add the wrapper package name
char *wn = (char*)PlugSubAlloc(g, NULL, strlen(m_Wrap) + 10);
m_Wrap = strcat(strcpy(wn, "wrappers/"), m_Wrap);
} // endif m_Wrap
fp = NULL;
m_Opened = false;
m_Connected = false;
m_Rows = 0;
//*m_ErrMsg = '\0';
} // end of JAVAConn
//JAVAConn::~JAVAConn()
// {
//if (Connected())
// EndCom();
// } // end of ~JAVAConn
/***********************************************************************/
/* Screen for errors. */
/***********************************************************************/
bool JAVAConn::Check(jint rc)
{
jstring s;
if (env->ExceptionCheck()) {
jthrowable exc = env->ExceptionOccurred();
jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"),
"toString", "()Ljava/lang/String;");
if (exc != nullptr && tid != nullptr) {
jstring s = (jstring)env->CallObjectMethod(exc, tid);
const char *utf = env->GetStringUTFChars(s, (jboolean)false);
env->DeleteLocalRef(s);
Msg = PlugDup(m_G, utf);
} else
Msg = "Exception occured";
env->ExceptionClear();
} else if (rc < 0) {
s = (jstring)env->CallObjectMethod(job, errid);
Msg = (char*)env->GetStringUTFChars(s, (jboolean)false);
} else
Msg = NULL;
return (Msg != NULL);
} // end of Check
/***********************************************************************/
/* Get MethodID if not exists yet. */
/***********************************************************************/
bool JAVAConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig)
{
if (mid == nullptr) {
mid = env->GetMethodID(jdi, name, sig);
if (Check()) {
strcpy(g->Message, Msg);
return true;
} else
return false;
} else
return false;
} // end of gmID
#if 0
/***********************************************************************/
/* Utility routine. */
/***********************************************************************/
int JAVAConn::GetMaxValue(int n)
{
jint m;
jmethodID maxid = nullptr;
if (gmID(m_G, maxid, "GetMaxValue", "(I)I"))
return -1;
// call method
if (Check(m = env->CallIntMethod(job, maxid, n)))
htrc("GetMaxValue: %s", Msg);
return (int)m;
} // end of GetMaxValue
#endif // 0
/***********************************************************************/
/* Reset the JVM library. */
/***********************************************************************/
void JAVAConn::ResetJVM(void)
{
if (LibJvm) {
#if defined(__WIN__)
FreeLibrary((HMODULE)LibJvm);
#else // !__WIN__
dlclose(LibJvm);
#endif // !__WIN__
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
} // endif LibJvm
} // end of ResetJVM
/***********************************************************************/
/* Dynamically link the JVM library. */
/* The purpose of this function is to allow using the CONNECT plugin */
/* for other table types when the Java JDK is not installed. */
/***********************************************************************/
bool JAVAConn::GetJVM(PGLOBAL g)
{
int ntry;
if (!LibJvm) {
char soname[512];
#if defined(__WIN__)
for (ntry = 0; !LibJvm && ntry < 3; ntry++) {
if (!ntry && JvmPath) {
strcat(strcpy(soname, JvmPath), "\\jvm.dll");
ntry = 3; // No other try
} else if (ntry < 2 && getenv("JAVA_HOME")) {
strcpy(soname, getenv("JAVA_HOME"));
if (ntry == 1)
strcat(soname, "\\jre");
strcat(soname, "\\bin\\client\\jvm.dll");
} else {
// Try to find it through the registry
char version[16];
char javaKey[64] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
LONG rc;
DWORD BufferSize = 16;
strcpy(soname, "jvm.dll"); // In case it fails
if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "CurrentVersion",
RRF_RT_ANY, NULL, (PVOID)&version, &BufferSize)) == ERROR_SUCCESS) {
strcat(strcat(javaKey, "\\"), version);
BufferSize = sizeof(soname);
if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "RuntimeLib",
RRF_RT_ANY, NULL, (PVOID)&soname, &BufferSize)) != ERROR_SUCCESS)
printf("RegGetValue: rc=%ld\n", rc);
} // endif rc
ntry = 3; // Try this only once
} // endelse
// Load the desired shared library
LibJvm = LoadLibrary(soname);
} // endfor ntry
// Get the needed entries
if (!LibJvm) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
} else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_CreateJavaVM"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
} else if (!(GetCreatedJavaVMs = (GETJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_GetCreatedJavaVMs"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
#if defined(_DEBUG)
} else if (!(GetDefaultJavaVMInitArgs = (GETDEF)GetProcAddress((HINSTANCE)LibJvm,
"JNI_GetDefaultJavaVMInitArgs"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(),
"JNI_GetDefaultJavaVMInitArgs");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
#else // !__WIN__
const char *error = NULL;
for (ntry = 0; !LibJvm && ntry < 2; ntry++) {
if (!ntry && JvmPath) {
strcat(strcpy(soname, JvmPath), "/libjvm.so");
ntry = 2;
} else if (!ntry && getenv("JAVA_HOME")) {
// TODO: Replace i386 by a better guess
strcat(strcpy(soname, getenv("JAVA_HOME")), "/jre/lib/i386/client/libjvm.so");
} else { // Will need LD_LIBRARY_PATH to be set
strcpy(soname, "libjvm.so");
ntry = 2;
} // endelse
LibJvm = dlopen(soname, RTLD_LAZY);
} // endfor ntry
// Load the desired shared library
if (!LibJvm) {
error = dlerror();
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
} else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
} else if (!(GetCreatedJavaVMs = (GETJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
#if defined(_DEBUG)
} else if (!(GetDefaultJavaVMInitArgs = (GETDEF)dlsym(LibJvm,
"JNI_GetDefaultJavaVMInitArgs"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetDefaultJavaVMInitArgs", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
#endif // !__WIN__
} // endif LibJvm
return LibJvm == NULL;
} // end of GetJVM
/***********************************************************************/
/* Open: connect to a data source. */
/***********************************************************************/
bool JAVAConn::Open(PGLOBAL g)
{
bool brc = true, err = false;
jboolean jt = (trace > 0);
// Link or check whether jvm library was linked
if (GetJVM(g))
return true;
// Firstly check whether the jvm was already created
JavaVM* jvms[1];
jsize jsz;
jint rc = GetCreatedJavaVMs(jvms, 1, &jsz);
if (rc == JNI_OK && jsz == 1) {
// jvm already existing
jvm = jvms[0];
rc = jvm->AttachCurrentThread((void**)&env, nullptr);
if (rc != JNI_OK) {
strcpy(g->Message, "Cannot attach jvm to the current thread");
return true;
} // endif rc
} else {
/*******************************************************************/
/* Create a new jvm */
/*******************************************************************/
PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path=.");
char *cp = NULL;
char sep;
#if defined(__WIN__)
sep = ';';
#define N 1
//#define N 2
//#define N 3
#else
sep = ':';
#define N 1
#endif
// Add wrappers jar files
AddJars(jpop, sep);
//================== prepare loading of Java VM ============================
JavaVMInitArgs vm_args; // Initialization arguments
JavaVMOption* options = new JavaVMOption[N]; // JVM invocation options
// where to find java .class
if (ClassPath && *ClassPath) {
jpop->Append(sep);
jpop->Append(ClassPath);
} // endif ClassPath
// Java source will be compiled as a jar file installed in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JdbcInterface.jar");
// All wrappers are pre-compiled in JavaWrappers.jar in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JavaWrappers.jar");
if ((cp = getenv("CLASSPATH"))) {
jpop->Append(sep);
jpop->Append(cp);
} // endif cp
if (trace) {
htrc("ClassPath=%s\n", ClassPath);
htrc("CLASSPATH=%s\n", cp);
htrc("%s\n", jpop->GetStr());
} // endif trace
options[0].optionString = jpop->GetStr();
#if N == 2
options[1].optionString = "-Xcheck:jni";
#endif
#if N == 3
options[1].optionString = "-Xms256M";
options[2].optionString = "-Xmx512M";
#endif
#if defined(_DEBUG)
vm_args.version = JNI_VERSION_1_2; // minimum Java version
rc = GetDefaultJavaVMInitArgs(&vm_args);
#else
vm_args.version = JNI_VERSION_1_6; // minimum Java version
#endif // _DEBUG
vm_args.nOptions = N; // number of options
vm_args.options = options;
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
//=============== load and initialize Java VM and JNI interface =============
rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
delete options; // we then no longer need the initialisation options.
switch (rc) {
case JNI_OK:
strcpy(g->Message, "VM successfully created");
brc = false;
break;
case JNI_ERR:
strcpy(g->Message, "Initialising JVM failed: unknown error");
break;
case JNI_EDETACHED:
strcpy(g->Message, "Thread detached from the VM");
break;
case JNI_EVERSION:
strcpy(g->Message, "JNI version error");
break;
case JNI_ENOMEM:
strcpy(g->Message, "Not enough memory");
break;
case JNI_EEXIST:
strcpy(g->Message, "VM already created");
break;
case JNI_EINVAL:
strcpy(g->Message, "Invalid arguments");
break;
default:
sprintf(g->Message, "Unknown return code %d", (int)rc);
break;
} // endswitch rc
if (trace)
htrc("%s\n", g->Message);
if (brc)
return true;
//=============== Display JVM version ===============
jint ver = env->GetVersion();
printf("JVM Version %d.%d\n", ((ver >> 16) & 0x0f), (ver & 0x0f));
} // endif rc
// try to find the java wrapper class
jdi = env->FindClass(m_Wrap);
if (jdi == nullptr) {
sprintf(g->Message, "ERROR: class %s not found!", m_Wrap);
return true;
} // endif jdi
#if 0 // Suppressed because it does not make any usable change
if (b && jpath && *jpath) {
// Try to add that path the the jvm class path
jmethodID alp = env->GetStaticMethodID(jdi, "addLibraryPath",
"(Ljava/lang/String;)I");
if (alp == nullptr) {
env->ExceptionDescribe();
env->ExceptionClear();
} else {
char *msg;
jstring path = env->NewStringUTF(jpath);
rc = env->CallStaticIntMethod(jdi, alp, path);
if ((msg = Check(rc))) {
strcpy(g->Message, msg);
env->DeleteLocalRef(path);
return RC_FX;
} else switch (rc) {
case JNI_OK:
printf("jpath added\n");
break;
case JNI_EEXIST:
printf("jpath already exist\n");
break;
case JNI_ERR:
default:
strcpy(g->Message, "Error adding jpath");
env->DeleteLocalRef(path);
return RC_FX;
} // endswitch rc
env->DeleteLocalRef(path);
} // endif alp
} // endif jpath
#endif // 0
// if class found, continue
jmethodID ctor = env->GetMethodID(jdi, "<init>", "(Z)V");
if (ctor == nullptr) {
sprintf(g->Message, "ERROR: %s constructor not found!", m_Wrap);
return true;
} else
job = env->NewObject(jdi, ctor, jt);
if (job == nullptr) {
sprintf(g->Message, "%s class object not constructed!", m_Wrap);
return true;
} // endif job
// If the object is successfully constructed,
// we can then search for the method we want to call,
// and invoke it for the object:
errid = env->GetMethodID(jdi, "GetErrmsg", "()Ljava/lang/String;");
if (env->ExceptionCheck()) {
strcpy(g->Message, "ERROR: method GetErrmsg() not found!");
env->ExceptionDescribe();
env->ExceptionClear();
return true;
} // endif Check
/*********************************************************************/
/* Link a Fblock. This make possible to automatically close it */
/* in case of error (throw). */
/*********************************************************************/
PDBUSER dbuserp = (PDBUSER)g->Activityp->Aptr;
fp = (PFBLOCK)PlugSubAlloc(g, NULL, sizeof(FBLOCK));
fp->Type = TYPE_FB_JAVA;
fp->Fname = NULL;
fp->Next = dbuserp->Openlist;
dbuserp->Openlist = fp;
fp->Count = 1;
fp->Length = 0;
fp->Memory = NULL;
fp->Mode = MODE_ANY;
fp->File = this;
fp->Handle = 0;
m_Opened = true;
return false;
} // end of Open
/***********************************************************************/
/* Disconnect connection */
/***********************************************************************/
void JAVAConn::Close()
{
jint rc;
if (m_Connected) {
jmethodID did = nullptr;
// Could have been detached in case of join
rc = jvm->AttachCurrentThread((void**)&env, nullptr);
if (gmID(m_G, did, DiscFunc, "()I"))
printf("%s\n", Msg);
else if (Check(env->CallIntMethod(job, did)))
printf("%s: %s\n", DiscFunc, Msg);
m_Connected = false;
} // endif m_Connected
if ((rc = jvm->DetachCurrentThread()) != JNI_OK)
printf("DetachCurrentThread: rc=%d\n", (int)rc);
if (fp)
fp->Count = 0;
m_Opened = false;
} // end of Close

129
storage/connect/javaconn.h Normal file
View File

@@ -0,0 +1,129 @@
/***********************************************************************/
/* JavaConn.h : header file for the Java connection classes. */
/***********************************************************************/
/***********************************************************************/
/* Included C-definition files required by the interface. */
/***********************************************************************/
#include "block.h"
#include "jdbccat.h"
/***********************************************************************/
/* Java native interface. */
/***********************************************************************/
#include <jni.h>
/***********************************************************************/
/* Constants and defines. */
/***********************************************************************/
// Miscellaneous sizing info
#define MAX_NUM_OF_MSG 10 // Max number of error messages
//efine MAX_CURRENCY 30 // Max size of Currency($) string
#define MAX_TNAME_LEN 32 // Max size of table names
//efine MAX_FNAME_LEN 256 // Max size of field names
//efine MAX_STRING_INFO 256 // Max size of string from SQLGetInfo
//efine MAX_DNAME_LEN 256 // Max size of Recordset names
//efine MAX_CONNECT_LEN 512 // Max size of Connect string
//efine MAX_CURSOR_NAME 18 // Max size of a cursor name
//efine DEFAULT_FIELD_TYPE 0 // TYPE_NULL
#if !defined(__WIN__)
typedef unsigned char *PUCHAR;
#endif // !__WIN__
enum JCATINFO {
JCAT_TAB = 1, // JDBC Tables
JCAT_COL = 2, // JDBC Columns
JCAT_KEY = 3, // JDBC PrimaryKeys
};
/***********************************************************************/
/* This structure is used to control the catalog functions. */
/***********************************************************************/
typedef struct tagJCATPARM {
JCATINFO Id; // Id to indicate function
PQRYRES Qrp; // Result set pointer
PCSZ DB; // Database (Schema)
PCSZ Tab; // Table name or pattern
PCSZ Pat; // Table type or column pattern
} JCATPARM;
typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *);
typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *);
#if defined(_DEBUG)
typedef jint(JNICALL *GETDEF) (void *);
#endif // _DEBUG
class JAVAConn;
/***********************************************************************/
/* JAVAConn class. */
/***********************************************************************/
class JAVAConn : public BLOCK {
friend class TDBJMG;
friend class JMGDISC;
private:
JAVAConn(); // Standard (unused) constructor
public:
// Constructor
JAVAConn(PGLOBAL g, PCSZ wrapper);
// Set static variables
static void SetJVM(void) {
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
} // end of SetJVM
static void ResetJVM(void);
static bool GetJVM(PGLOBAL g);
// Implementation
public:
//virtual ~JAVAConn();
bool IsOpen(void) { return m_Opened; }
bool IsConnected(void) { return m_Connected; }
// Java operations
protected:
bool gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig);
bool Check(jint rc = 0);
public:
virtual void AddJars(PSTRG jpop, char sep) = 0;
virtual bool Connect(PJPARM sop) = 0;
virtual bool Open(PGLOBAL g);
virtual bool MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
PCSZ filter, bool pipe) = 0;
virtual void Close(void);
protected:
// Members
#if defined(__WIN__)
static HANDLE LibJvm; // Handle to the jvm DLL
#else // !__WIN__
static void *LibJvm; // Handle for the jvm shared library
#endif // !__WIN__
static CRTJVM CreateJavaVM;
static GETJVM GetCreatedJavaVMs;
#if defined(_DEBUG)
static GETDEF GetDefaultJavaVMInitArgs;
#endif // _DEBUG
PGLOBAL m_G;
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env; // Pointer to native interface
jclass jdi; // Pointer to the java wrapper class
jobject job; // The java wrapper class object
jmethodID errid; // The GetErrmsg method ID
PFBLOCK fp;
bool m_Opened;
bool m_Connected;
PCSZ DiscFunc;
PCSZ Msg;
PCSZ m_Wrap;
int m_Rows;
}; // end of JAVAConn class definition

View File

@@ -1,3 +1,6 @@
#ifndef __JDBCCAT_H
#define __JDBCCAT_H
// Timeout and net wait defaults
#define DEFAULT_LOGIN_TIMEOUT -1 // means do not set
#define DEFAULT_QUERY_TIMEOUT -1 // means do not set
@@ -8,9 +11,9 @@ typedef struct jdbc_parms {
PCSZ Url; // Driver URL
PCSZ User; // User connect info
PCSZ Pwd; // Password connect info
//char *Properties; // Connection property list
//int Cto; // Connect timeout
//int Qto; // Query timeout
int Version; // Driver version
int Fsize; // Fetch size
bool Scrollable; // Scrollable cursor
} JDBCPARM, *PJPARM;
@@ -28,3 +31,5 @@ PQRYRES JDBCSrcCols(PGLOBAL g, PCSZ src, PJPARM sop);
PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat,
PCSZ tabtyp, int maxres, bool info, PJPARM sop);
PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info);
#endif // __JDBCCAT_H

View File

@@ -53,38 +53,28 @@
#include "osutil.h"
#if defined(__WIN__)
extern "C" HINSTANCE s_hModule; // Saved module handle
#endif // __WIN__
//#if defined(__WIN__)
//extern "C" HINSTANCE s_hModule; // Saved module handle
//#endif // __WIN__
#define nullptr 0
TYPCONV GetTypeConv();
int GetConvSize();
extern char *JvmPath; // The connect_jvm_path global variable value
extern char *ClassPath; // The connect_class_path global variable value
//extern char *JvmPath; // The connect_jvm_path global variable value
//extern char *ClassPath; // The connect_class_path global variable value
char *GetJavaWrapper(void); // The connect_java_wrapper variable value
/***********************************************************************/
/* Static JDBConn objects. */
/***********************************************************************/
void *JDBConn::LibJvm = NULL;
CRTJVM JDBConn::CreateJavaVM = NULL;
GETJVM JDBConn::GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GETDEF JDBConn::GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
//char *GetJavaWrapper(void); // The connect_java_wrapper variable value
/***********************************************************************/
/* Some macro's (should be defined elsewhere to be more accessible) */
/***********************************************************************/
#if defined(_DEBUG)
#define ASSERT(f) assert(f)
#define DEBUG_ONLY(f) (f)
#else // !_DEBUG
#define ASSERT(f) ((void)0)
#define DEBUG_ONLY(f) ((void)0)
#endif // !_DEBUG
//#if defined(_DEBUG)
//#define ASSERT(f) assert(f)
//#define DEBUG_ONLY(f) (f)
//#else // !_DEBUG
//#define ASSERT(f) ((void)0)
//#define DEBUG_ONLY(f) ((void)0)
//#endif // !_DEBUG
// To avoid gcc warning
int TranslateJDBCType(int stp, char *tn, int prec, int& len, char& v);
@@ -239,11 +229,11 @@ PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_REM};
unsigned int length[] = {0, 0, 0, 0, 6, 0, 10, 10, 6, 6, 6, 0};
bool b[] = {true, true, false, false, false, false, false, false, true, true, false, true};
int i, n, ncol = 12;
PCOLRES crp;
PQRYRES qrp;
int i, n, ncol = 12;
PCOLRES crp;
PQRYRES qrp;
JCATPARM *cap;
JDBConn *jcp = NULL;
JDBConn *jcp = NULL;
/************************************************************************/
/* Do an evaluation of the result size. */
@@ -251,7 +241,7 @@ PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
if (!info) {
jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(sjp) != RC_OK) // openReadOnly + noJDBCdialog
if (jcp->Connect(sjp)) // openReadOnly + noJDBCdialog
return NULL;
if (table && !strchr(table, '%')) {
@@ -299,7 +289,7 @@ PQRYRES JDBCColumns(PGLOBAL g, PCSZ db, PCSZ table, PCSZ colpat,
if (trace)
htrc("Getting col results ncol=%d\n", qrp->Nbcol);
if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp)))
if (!(cap = AllocCatInfo(g, JCAT_COL, db, table, qrp)))
return NULL;
// Colpat cannot be null or empty for some drivers
@@ -337,7 +327,7 @@ PQRYRES JDBCSrcCols(PGLOBAL g, PCSZ src, PJPARM sjp)
PQRYRES qrp;
JDBConn *jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(sjp))
if (jcp->Connect(sjp))
return NULL;
if (strstr(src, "%s")) {
@@ -379,7 +369,7 @@ PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
/**********************************************************************/
jcp = new(g)JDBConn(g, NULL);
if (jcp->Open(sjp) == RC_FX)
if (jcp->Connect(sjp))
return NULL;
if (!maxres)
@@ -420,7 +410,7 @@ PQRYRES JDBCTables(PGLOBAL g, PCSZ db, PCSZ tabpat, PCSZ tabtyp,
return qrp;
// Tabpat cannot be null or empty for some drivers
if (!(cap = AllocCatInfo(g, CAT_TAB, db,
if (!(cap = AllocCatInfo(g, JCAT_TAB, db,
(tabpat && *tabpat) ? tabpat : PlugDup(g, "%"), qrp)))
return NULL;
@@ -475,7 +465,7 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
if (!info) {
jcp = new(g) JDBConn(g, NULL);
if (jcp->Open(NULL) != RC_OK)
if (jcp->Open(g) != RC_OK)
return NULL;
if (!maxres)
@@ -523,37 +513,16 @@ PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info)
/***********************************************************************/
/* JDBConn construction/destruction. */
/***********************************************************************/
JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
JDBConn::JDBConn(PGLOBAL g, PCSZ wrapper) : JAVAConn(g, wrapper)
{
m_G = g;
m_Tdb = tdbp;
jvm = nullptr; // Pointer to the JVM (Java Virtual Machine)
env= nullptr; // Pointer to native interface
jdi = nullptr; // Pointer to the java wrapper class
job = nullptr; // The java wrapper class object
xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr;
prepid = xpid = pcid = nullptr;
chrfldid = intfldid = dblfldid = fltfldid = bigfldid = nullptr;
objfldid = datfldid = timfldid = tspfldid = nullptr;
//m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT;
//m_QueryTimeout = DEFAULT_QUERY_TIMEOUT;
//m_UpdateOptions = 0;
Msg = NULL;
m_Wrap = (tdbp && tdbp->WrapName) ? tdbp->WrapName : GetJavaWrapper();
if (!strchr(m_Wrap, '/')) {
// Add the wrapper package name
char *wn = (char*)PlugSubAlloc(g, NULL, strlen(m_Wrap) + 10);
m_Wrap = strcat(strcpy(wn, "wrappers/"), m_Wrap);
} // endif m_Wrap
//m_Driver = NULL;
//m_Url = NULL;
//m_User = NULL;
//m_Pwd = NULL;
DiscFunc = "JdbcDisconnect";
m_Ncol = 0;
m_Aff = 0;
m_Rows = 0;
//m_Rows = 0;
m_Fetch = 0;
m_RowsetSize = 0;
m_Updatable = true;
@@ -563,7 +532,6 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
m_Opened = false;
m_IDQuoteChar[0] = '"';
m_IDQuoteChar[1] = 0;
//*m_ErrMsg = '\0';
} // end of JDBConn
//JDBConn::~JDBConn()
@@ -573,55 +541,6 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp)
// } // end of ~JDBConn
/***********************************************************************/
/* Screen for errors. */
/***********************************************************************/
bool JDBConn::Check(jint rc)
{
jstring s;
if (env->ExceptionCheck()) {
jthrowable exc = env->ExceptionOccurred();
jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"),
"toString", "()Ljava/lang/String;");
if (exc != nullptr && tid != nullptr) {
jstring s = (jstring)env->CallObjectMethod(exc, tid);
const char *utf = env->GetStringUTFChars(s, (jboolean)false);
env->DeleteLocalRef(s);
Msg = PlugDup(m_G, utf);
} else
Msg = "Exception occured";
env->ExceptionClear();
} else if (rc < 0) {
s = (jstring)env->CallObjectMethod(job, errid);
Msg = (char*)env->GetStringUTFChars(s, (jboolean)false);
} else
Msg = NULL;
return (Msg != NULL);
} // end of Check
/***********************************************************************/
/* Get MethodID if not exists yet. */
/***********************************************************************/
bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig)
{
if (mid == nullptr) {
mid = env->GetMethodID(jdi, name, sig);
if (Check()) {
strcpy(g->Message, Msg);
return true;
} else
return false;
} else
return false;
} // end of gmID
/***********************************************************************/
/* Utility routine. */
/***********************************************************************/
@@ -641,381 +560,52 @@ int JDBConn::GetMaxValue(int n)
} // end of GetMaxValue
/***********************************************************************/
/* Reset the JVM library. */
/* AddJars: add some jar file to the Class path. */
/***********************************************************************/
void JDBConn::ResetJVM(void)
void JDBConn::AddJars(PSTRG jpop, char sep)
{
if (LibJvm) {
#if defined(__WIN__)
FreeLibrary((HMODULE)LibJvm);
#else // !__WIN__
dlclose(LibJvm);
#endif // !__WIN__
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
} // endif LibJvm
} // end of ResetJVM
#if defined(DEVELOPMENT)
jpop->Append(
";C:/Jconnectors/postgresql-9.4.1208.jar"
";C:/Oracle/ojdbc7.jar"
";C:/Apache/commons-dbcp2-2.1.1/commons-dbcp2-2.1.1.jar"
";C:/Apache/commons-pool2-2.4.2/commons-pool2-2.4.2.jar"
";C:/Apache/commons-logging-1.2/commons-logging-1.2.jar"
";C:/Jconnectors/mysql-connector-java-6.0.2-bin.jar"
";C:/Jconnectors/mariadb-java-client-2.0.1.jar"
";C:/Jconnectors/sqljdbc42.jar");
#endif // DEVELOPMENT
} // end of AddJars
/***********************************************************************/
/* Dynamically link the JVM library. */
/* The purpose of this function is to allow using the CONNECT plugin */
/* for other table types when the Java JDK is not installed. */
/* Connect: connect to a data source. */
/***********************************************************************/
bool JDBConn::GetJVM(PGLOBAL g)
{
int ntry;
if (!LibJvm) {
char soname[512];
#if defined(__WIN__)
for (ntry = 0; !LibJvm && ntry < 3; ntry++) {
if (!ntry && JvmPath) {
strcat(strcpy(soname, JvmPath), "\\jvm.dll");
ntry = 3; // No other try
} else if (ntry < 2 && getenv("JAVA_HOME")) {
strcpy(soname, getenv("JAVA_HOME"));
if (ntry == 1)
strcat(soname, "\\jre");
strcat(soname, "\\bin\\client\\jvm.dll");
} else {
// Try to find it through the registry
char version[16];
char javaKey[64] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
LONG rc;
DWORD BufferSize = 16;
strcpy(soname, "jvm.dll"); // In case it fails
if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "CurrentVersion",
RRF_RT_ANY, NULL, (PVOID)&version, &BufferSize)) == ERROR_SUCCESS) {
strcat(strcat(javaKey, "\\"), version);
BufferSize = sizeof(soname);
if ((rc = RegGetValue(HKEY_LOCAL_MACHINE, javaKey, "RuntimeLib",
RRF_RT_ANY, NULL, (PVOID)&soname, &BufferSize)) != ERROR_SUCCESS)
printf("RegGetValue: rc=%ld\n", rc);
} // endif rc
ntry = 3; // Try this only once
} // endelse
// Load the desired shared library
LibJvm = LoadLibrary(soname);
} // endfor ntry
// Get the needed entries
if (!LibJvm) {
char buf[256];
DWORD rc = GetLastError();
sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
(LPTSTR)buf, sizeof(buf), NULL);
strcat(strcat(g->Message, ": "), buf);
} else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_CreateJavaVM"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
} else if (!(GetCreatedJavaVMs = (GETJVM)GetProcAddress((HINSTANCE)LibJvm,
"JNI_GetCreatedJavaVMs"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
#if defined(_DEBUG)
} else if (!(GetDefaultJavaVMInitArgs = (GETDEF)GetProcAddress((HINSTANCE)LibJvm,
"JNI_GetDefaultJavaVMInitArgs"))) {
sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(),
"JNI_GetDefaultJavaVMInitArgs");
FreeLibrary((HMODULE)LibJvm);
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
#else // !__WIN__
const char *error = NULL;
for (ntry = 0; !LibJvm && ntry < 2; ntry++) {
if (!ntry && JvmPath) {
strcat(strcpy(soname, JvmPath), "/libjvm.so");
ntry = 2;
} else if (!ntry && getenv("JAVA_HOME")) {
// TODO: Replace i386 by a better guess
strcat(strcpy(soname, getenv("JAVA_HOME")), "/jre/lib/i386/client/libjvm.so");
} else { // Will need LD_LIBRARY_PATH to be set
strcpy(soname, "libjvm.so");
ntry = 2;
} // endelse
LibJvm = dlopen(soname, RTLD_LAZY);
} // endfor ntry
// Load the desired shared library
if (!LibJvm) {
error = dlerror();
sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error));
} else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
} else if (!(GetCreatedJavaVMs = (GETJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
#if defined(_DEBUG)
} else if (!(GetDefaultJavaVMInitArgs = (GETDEF)dlsym(LibJvm,
"JNI_GetDefaultJavaVMInitArgs"))) {
error = dlerror();
sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetDefaultJavaVMInitArgs", SVP(error));
dlclose(LibJvm);
LibJvm = NULL;
#endif // _DEBUG
} // endif LibJvm
#endif // !__WIN__
} // endif LibJvm
return LibJvm == NULL;
} // end of GetJVM
/***********************************************************************/
/* Open: connect to a data source. */
/***********************************************************************/
int JDBConn::Open(PJPARM sop)
bool JDBConn::Connect(PJPARM sop)
{
int irc = RC_FX;
bool err = false;
jint rc;
jboolean jt = (trace > 0);
PGLOBAL& g = m_G;
// Link or check whether jvm library was linked
if (GetJVM(g))
return RC_FX;
// Firstly check whether the jvm was already created
JavaVM* jvms[1];
jsize jsz;
jint rc = GetCreatedJavaVMs(jvms, 1, &jsz);
if (rc == JNI_OK && jsz == 1) {
// jvm already existing
jvm = jvms[0];
rc = jvm->AttachCurrentThread((void**)&env, nullptr);
if (rc != JNI_OK) {
strcpy(g->Message, "Cannot attach jvm to the current thread");
return RC_FX;
} // endif rc
} else {
/*******************************************************************/
/* Create a new jvm */
/*******************************************************************/
PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path=.");
char *cp = NULL;
char sep;
#if defined(__WIN__)
sep = ';';
#define N 1
//#define N 2
//#define N 3
#else
sep = ':';
#define N 1
#endif
// Java source will be compiled as a jar file installed in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JdbcInterface.jar");
// All wrappers are pre-compiled in JavaWrappers.jar in the plugin dir
jpop->Append(sep);
jpop->Append(GetPluginDir());
jpop->Append("JavaWrappers.jar");
//================== prepare loading of Java VM ============================
JavaVMInitArgs vm_args; // Initialization arguments
JavaVMOption* options = new JavaVMOption[N]; // JVM invocation options
// where to find java .class
if (ClassPath && *ClassPath) {
jpop->Append(sep);
jpop->Append(ClassPath);
} // endif ClassPath
if ((cp = getenv("CLASSPATH"))) {
jpop->Append(sep);
jpop->Append(cp);
} // endif cp
if (trace) {
htrc("ClassPath=%s\n", ClassPath);
htrc("CLASSPATH=%s\n", cp);
htrc("%s\n", jpop->GetStr());
} // endif trace
options[0].optionString = jpop->GetStr();
#if N == 2
options[1].optionString = "-Xcheck:jni";
#endif
#if N == 3
options[1].optionString = "-Xms256M";
options[2].optionString = "-Xmx512M";
#endif
#if defined(_DEBUG)
vm_args.version = JNI_VERSION_1_2; // minimum Java version
rc = GetDefaultJavaVMInitArgs(&vm_args);
#else
vm_args.version = JNI_VERSION_1_6; // minimum Java version
#endif // _DEBUG
vm_args.nOptions = N; // number of options
vm_args.options = options;
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
//=============== load and initialize Java VM and JNI interface =============
rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
delete options; // we then no longer need the initialisation options.
switch (rc) {
case JNI_OK:
strcpy(g->Message, "VM successfully created");
irc = RC_OK;
break;
case JNI_ERR:
strcpy(g->Message, "Initialising JVM failed: unknown error");
break;
case JNI_EDETACHED:
strcpy(g->Message, "Thread detached from the VM");
break;
case JNI_EVERSION:
strcpy(g->Message, "JNI version error");
break;
case JNI_ENOMEM:
strcpy(g->Message, "Not enough memory");
break;
case JNI_EEXIST:
strcpy(g->Message, "VM already created");
break;
case JNI_EINVAL:
strcpy(g->Message, "Invalid arguments");
break;
default:
sprintf(g->Message, "Unknown return code %d", (int)rc);
break;
} // endswitch rc
if (trace)
htrc("%s\n", g->Message);
if (irc != RC_OK)
return irc;
//=============== Display JVM version ===============
jint ver = env->GetVersion();
printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f));
} // endif rc
// try to find the java wrapper class
jdi = env->FindClass(m_Wrap);
if (jdi == nullptr) {
sprintf(g->Message, "ERROR: class %s not found!", m_Wrap);
return RC_FX;
} // endif jdi
#if 0 // Suppressed because it does not make any usable change
if (b && jpath && *jpath) {
// Try to add that path the the jvm class path
jmethodID alp = env->GetStaticMethodID(jdi, "addLibraryPath",
"(Ljava/lang/String;)I");
if (alp == nullptr) {
env->ExceptionDescribe();
env->ExceptionClear();
} else {
char *msg;
jstring path = env->NewStringUTF(jpath);
rc = env->CallStaticIntMethod(jdi, alp, path);
if ((msg = Check(rc))) {
strcpy(g->Message, msg);
env->DeleteLocalRef(path);
return RC_FX;
} else switch (rc) {
case JNI_OK:
printf("jpath added\n");
break;
case JNI_EEXIST:
printf("jpath already exist\n");
break;
case JNI_ERR:
default:
strcpy(g->Message, "Error adding jpath");
env->DeleteLocalRef(path);
return RC_FX;
} // endswitch rc
env->DeleteLocalRef(path);
} // endif alp
} // endif jpath
#endif // 0
// if class found, continue
jmethodID ctor = env->GetMethodID(jdi, "<init>", "(Z)V");
if (ctor == nullptr) {
sprintf(g->Message, "ERROR: %s constructor not found!", m_Wrap);
return RC_FX;
} else
job = env->NewObject(jdi, ctor, jt);
// If the object is successfully constructed,
// we can then search for the method we want to call,
// and invoke it for the object:
if (job == nullptr) {
sprintf(g->Message, "%s class object not constructed!", m_Wrap);
return RC_FX;
} // endif job
errid = env->GetMethodID(jdi, "GetErrmsg", "()Ljava/lang/String;");
if (env->ExceptionCheck()) {
strcpy(g->Message, "ERROR: method GetErrmsg() not found!");
env->ExceptionDescribe();
env->ExceptionClear();
return RC_FX;
} // endif Check
/*******************************************************************/
/* Create or attach a JVM. */
/*******************************************************************/
if (Open(g))
return true;
if (!sop) // DRIVER catalog table
return RC_OK;
return false;
jmethodID cid = nullptr;
if (gmID(g, cid, "JdbcConnect", "([Ljava/lang/String;IZ)I"))
return RC_FX;
return true;
// Build the java string array
jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4
env->FindClass("java/lang/String"), NULL); // Strings
//m_Driver = sop->Driver;
//m_Url = sop->Url;
//m_User = sop->User;
//m_Pwd = sop->Pwd;
m_Scrollable = sop->Scrollable;
m_RowsetSize = sop->Fsize;
//m_LoginTimeout = sop->Cto;
@@ -1035,9 +625,6 @@ int JDBConn::Open(PJPARM sop)
if (sop->Pwd)
env->SetObjectArrayElement(parms, 3, env->NewStringUTF(sop->Pwd));
//if (sop->Properties)
// env->SetObjectArrayElement(parms, 4, env->NewStringUTF(sop->Properties));
// call method
rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable);
err = Check(rc);
@@ -1045,7 +632,7 @@ int JDBConn::Open(PJPARM sop)
if (err) {
sprintf(g->Message, "Connecting: %s rc=%d", Msg, (int)rc);
return RC_FX;
return true;
} // endif Msg
jmethodID qcid = nullptr;
@@ -1064,17 +651,18 @@ int JDBConn::Open(PJPARM sop)
} // endif qcid
if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I"))
return RC_FX;
return true;
else
m_Opened = true;
return RC_OK;
} // end of Open
return false;
} // end of Connect
/***********************************************************************/
/* Execute an SQL command. */
/***********************************************************************/
int JDBConn::ExecSQLcommand(PCSZ sql)
int JDBConn::ExecuteCommand(PCSZ sql)
{
int rc;
jint n;
@@ -1110,7 +698,7 @@ int JDBConn::ExecSQLcommand(PCSZ sql)
} // endif ncol
return rc;
} // end of ExecSQLcommand
} // end of ExecuteCommand
/***********************************************************************/
/* Fetch next row. */
@@ -1170,38 +758,12 @@ int JDBConn::Rewind(PCSZ sql)
jboolean b = env->CallBooleanMethod(job, fetchid, 0);
rbuf = m_Rows;
} else if (ExecSQLcommand(sql) != RC_FX)
} else if (ExecuteCommand(sql) != RC_FX)
rbuf = 0;
return rbuf;
} // end of Rewind
/***********************************************************************/
/* Disconnect connection */
/***********************************************************************/
void JDBConn::Close()
{
if (m_Opened) {
jint rc;
jmethodID did = nullptr;
// Could have been detached in case of join
rc = jvm->AttachCurrentThread((void**)&env, nullptr);
if (gmID(m_G, did, "JdbcDisconnect", "()I"))
printf("%s\n", Msg);
else if (Check(env->CallIntMethod(job, did)))
printf("jdbcDisconnect: %s\n", Msg);
if ((rc = jvm->DetachCurrentThread()) != JNI_OK)
printf("DetachCurrentThread: rc=%d\n", (int)rc);
//rc = jvm->DestroyJavaVM();
m_Opened = false;
} // endif m_Opened
} // end of Close
/***********************************************************************/
/* Retrieve and set the column value from the result set. */
/***********************************************************************/
@@ -1215,7 +777,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
if (rank == 0)
if (!name || (jn = env->NewStringUTF(name)) == nullptr) {
sprintf(g->Message, "Fail to allocate jstring %s", SVP(name));
throw TYPE_AM_JDBC;
throw (int)TYPE_AM_JDBC;
} // endif name
// Returns 666 is case of error
@@ -1223,7 +785,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
if (Check((ctyp == 666) ? -1 : 1)) {
sprintf(g->Message, "Getting ctyp: %s", Msg);
throw TYPE_AM_JDBC;
throw (int)TYPE_AM_JDBC;
} // endif Check
if (val->GetNullable())
@@ -1334,7 +896,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val)
env->DeleteLocalRef(jn);
sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", Msg, rank, (int)ctyp);
throw TYPE_AM_JDBC;
throw (int)TYPE_AM_JDBC;
} // endif Check
if (rank == 0)
@@ -1424,7 +986,7 @@ int JDBConn::ExecuteUpdate(PCSZ sql)
/***********************************************************************/
/* Get the number of lines of the result set. */
/***********************************************************************/
int JDBConn::GetResultSize(PCSZ sql, JDBCCOL *colp)
int JDBConn::GetResultSize(PCSZ sql, PCOL colp)
{
int rc, n = 0;
@@ -1565,53 +1127,6 @@ bool JDBConn::SetParam(JDBCCOL *colp)
return rc;
} // end of SetParam
#if 0
/***********************************************************************/
/* Get the list of Data Sources and set it in qrp. */
/***********************************************************************/
bool JDBConn::GetDataSources(PQRYRES qrp)
{
bool rv = false;
UCHAR *dsn, *des;
UWORD dir = SQL_FETCH_FIRST;
SWORD n1, n2, p1, p2;
PCOLRES crp1 = qrp->Colresp, crp2 = qrp->Colresp->Next;
RETCODE rc;
n1 = crp1->Clen;
n2 = crp2->Clen;
try {
rc = SQLAllocEnv(&m_henv);
if (!Check(rc))
ThrowDJX(rc, "SQLAllocEnv"); // Fatal
for (int i = 0; i < qrp->Maxres; i++) {
dsn = (UCHAR*)crp1->Kdata->GetValPtr(i);
des = (UCHAR*)crp2->Kdata->GetValPtr(i);
rc = SQLDataSources(m_henv, dir, dsn, n1, &p1, des, n2, &p2);
if (rc == SQL_NO_DATA_FOUND)
break;
else if (!Check(rc))
ThrowDJX(rc, "SQLDataSources");
qrp->Nblin++;
dir = SQL_FETCH_NEXT;
} // endfor i
}
catch (DJX *x) {
sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0));
rv = true;
} // end try/catch
Close();
return rv;
} // end of GetDataSources
#endif // 0
/***********************************************************************/
/* Get the list of Drivers and set it in qrp. */
/***********************************************************************/
@@ -1677,7 +1192,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
jint *n = nullptr;
jstring label;
jmethodID colid = nullptr;
int rc = ExecSQLcommand(src);
int rc = ExecuteCommand(src);
if (rc == RC_NF) {
strcpy(g->Message, "Srcdef is not returning a result set");
@@ -1711,7 +1226,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
case 5: crp->Name = "Nullable"; break;
} // endswitch i
// Build the java string array
// Build the java int array
jintArray val = env->NewIntArray(4);
if (val == nullptr) {
@@ -1892,28 +1407,19 @@ bool JDBConn::SetParam(JDBCCOL *colp)
// Now do call the proper JDBC API
switch (cap->Id) {
case CAT_COL:
case JCAT_COL:
fnc = "GetColumns";
break;
case CAT_TAB:
case JCAT_TAB:
fnc = "GetTables";
break;
#if 0
case CAT_KEY:
case JCAT_KEY:
fnc = "SQLPrimaryKeys";
rc = SQLPrimaryKeys(hstmt, name.ptr(2), name.length(2),
name.ptr(1), name.length(1),
name.ptr(0), name.length(0));
break;
case CAT_STAT:
fnc = "SQLStatistics";
rc = SQLStatistics(hstmt, name.ptr(2), name.length(2),
name.ptr(1), name.length(1),
name.ptr(0), name.length(0),
cap->Unique, cap->Accuracy);
break;
case CAT_SPC:
ThrowDJX("SQLSpecialColumns not available yet");
#endif // 0
default:
sprintf(g->Message, "Invalid SQL function id");
@@ -2002,10 +1508,10 @@ bool JDBConn::SetParam(JDBCCOL *colp)
/***********************************************************************/
/* Allocate a CONNECT result structure from the JDBC result. */
/***********************************************************************/
PQRYRES JDBConn::AllocateResult(PGLOBAL g)
PQRYRES JDBConn::AllocateResult(PGLOBAL g, PTDB tdbp)
{
bool uns;
PJDBCCOL colp;
PCOL colp;
PCOLRES *pcrp, crp;
PQRYRES qrp;
@@ -2030,8 +1536,7 @@ bool JDBConn::SetParam(JDBCCOL *colp)
qrp->Nblin = 0;
qrp->Cursor = 0;
for (colp = (PJDBCCOL)m_Tdb->Columns; colp;
colp = (PJDBCCOL)colp->GetNext())
for (colp = tdbp->GetColumns(); colp; colp = colp->GetNext())
if (!colp->IsSpecial()) {
*pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES));
crp = *pcrp;
@@ -2059,10 +1564,9 @@ bool JDBConn::SetParam(JDBCCOL *colp)
memset(crp->Nulls, ' ', m_Rows);
} // endelse Nullable
colp->SetCrp(crp);
((EXTCOL*)colp)->SetCrp(crp);
} // endif colp
*pcrp = NULL;
//qrp->Nblin = n;
return qrp;
} // end of AllocateResult

View File

@@ -1,61 +1,7 @@
/***********************************************************************/
/* JDBConn.h : header file for the JDBC connection classes. */
/***********************************************************************/
//nclude <windows.h> /* Windows include file */
//nclude <windowsx.h> /* Message crackers */
/***********************************************************************/
/* Included C-definition files required by the interface. */
/***********************************************************************/
#include "block.h"
/***********************************************************************/
/* JDBC interface. */
/***********************************************************************/
#include <jni.h>
/***********************************************************************/
/* Constants and defines. */
/***********************************************************************/
// Miscellaneous sizing info
#define MAX_NUM_OF_MSG 10 // Max number of error messages
//efine MAX_CURRENCY 30 // Max size of Currency($) string
#define MAX_TNAME_LEN 32 // Max size of table names
//efine MAX_FNAME_LEN 256 // Max size of field names
//efine MAX_STRING_INFO 256 // Max size of string from SQLGetInfo
//efine MAX_DNAME_LEN 256 // Max size of Recordset names
//efine MAX_CONNECT_LEN 512 // Max size of Connect string
//efine MAX_CURSOR_NAME 18 // Max size of a cursor name
#define DEFAULT_FIELD_TYPE 0 // TYPE_NULL
#if !defined(__WIN__)
typedef unsigned char *PUCHAR;
#endif // !__WIN__
enum JCATINFO {
CAT_TAB = 1, // JDBC Tables
CAT_COL = 2, // JDBC Columns
CAT_KEY = 3, // JDBC PrimaryKeys
//CAT_STAT = 4, // SQLStatistics
//CAT_SPC = 5 // SQLSpecialColumns
};
/***********************************************************************/
/* This structure is used to control the catalog functions. */
/***********************************************************************/
typedef struct tagJCATPARM {
JCATINFO Id; // Id to indicate function
PQRYRES Qrp; // Result set pointer
PCSZ DB; // Database (Schema)
PCSZ Tab; // Table name or pattern
PCSZ Pat; // Table type or column pattern
} JCATPARM;
typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *);
typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *);
#if defined(_DEBUG)
typedef jint(JNICALL *GETDEF) (void *);
#endif // _DEBUG
#include "javaconn.h"
// JDBC connection to a data source
class TDBJDBC;
@@ -66,7 +12,7 @@ class TDBXJDC;
/***********************************************************************/
/* JDBConn class. */
/***********************************************************************/
class JDBConn : public BLOCK {
class JDBConn : public JAVAConn {
friend class TDBJDBC;
friend class TDBXJDC;
//friend PQRYRES GetColumnInfo(PGLOBAL, char*&, char *, int, PVBLK&);
@@ -74,118 +20,80 @@ private:
JDBConn(); // Standard (unused) constructor
public:
JDBConn(PGLOBAL g, TDBJDBC *tdbp);
// Constructor
JDBConn(PGLOBAL g, PCSZ wrapper);
int Open(PJPARM sop);
int Rewind(PCSZ sql);
void Close(void);
PQRYRES AllocateResult(PGLOBAL g);
virtual void AddJars(PSTRG jpop, char sep);
PQRYRES AllocateResult(PGLOBAL g, PTDB tdbp);
// Attributes
public:
char *GetQuoteChar(void) { return m_IDQuoteChar; }
// Database successfully opened?
bool IsOpen(void) { return m_Opened; }
//PSZ GetStringInfo(ushort infotype);
int GetMaxValue(int infotype);
//PSZ GetConnect(void) { return m_Connect; }
char *GetQuoteChar(void) { return m_IDQuoteChar; }
virtual int GetMaxValue(int infotype);
public:
// Operations
//void SetLoginTimeout(DWORD sec) {m_LoginTimeout = sec;}
//void SetQueryTimeout(DWORD sec) {m_QueryTimeout = sec;}
//void SetUserName(PSZ user) {m_User = user;}
//void SetUserPwd(PSZ pwd) {m_Pwd = pwd;}
int GetResultSize(PCSZ sql, JDBCCOL *colp);
int ExecuteQuery(PCSZ sql);
int ExecuteUpdate(PCSZ sql);
int Fetch(int pos = 0);
virtual bool Connect(PJPARM sop);
virtual bool MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
PCSZ filter, bool pipe) {return true;}
virtual int GetResultSize(PCSZ sql, PCOL colp);
virtual int ExecuteCommand(PCSZ sql);
virtual int ExecuteQuery(PCSZ sql);
virtual int ExecuteUpdate(PCSZ sql);
virtual int Fetch(int pos = 0);
virtual void SetColumnValue(int rank, PSZ name, PVAL val);
// Jdbc operations
bool PrepareSQL(PCSZ sql);
int ExecuteSQL(void);
int ExecuteSQL(void); // Prepared statement
bool SetParam(JDBCCOL *colp);
int ExecSQLcommand(PCSZ sql);
void SetColumnValue(int rank, PSZ name, PVAL val);
int GetCatInfo(JCATPARM *cap);
//bool GetDataSources(PQRYRES qrp);
bool GetDrivers(PQRYRES qrp);
PQRYRES GetMetaData(PGLOBAL g, PCSZ src);
public:
// Set static variables
static void SetJVM(void) {
LibJvm = NULL;
CreateJavaVM = NULL;
GetCreatedJavaVMs = NULL;
#if defined(_DEBUG)
GetDefaultJavaVMInitArgs = NULL;
#endif // _DEBUG
} // end of SetJVM
static void ResetJVM(void);
static bool GetJVM(PGLOBAL g);
int Rewind(PCSZ sql);
// Implementation
public:
//virtual ~JDBConn();
// JDBC operations
protected:
bool gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig);
bool Check(jint rc = 0);
//void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/);
//void ThrowDJX(PSZ msg);
//void Free(void);
protected:
// Members
#if defined(__WIN__)
static HANDLE LibJvm; // Handle to the jvm DLL
#else // !__WIN__
static void *LibJvm; // Handle for the jvm shared library
#endif // !__WIN__
static CRTJVM CreateJavaVM;
static GETJVM GetCreatedJavaVMs;
#if defined(_DEBUG)
static GETDEF GetDefaultJavaVMInitArgs;
#endif // _DEBUG
PGLOBAL m_G;
TDBJDBC *m_Tdb;
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env; // Pointer to native interface
jclass jdi; // Pointer to the java wrapper class
jobject job; // The java wrapper class object
jmethodID xqid; // The ExecuteQuery method ID
jmethodID xuid; // The ExecuteUpdate method ID
jmethodID xid; // The Execute method ID
jmethodID grs; // The GetResult method ID
jmethodID readid; // The ReadNext method ID
jmethodID fetchid; // The Fetch method ID
jmethodID typid; // The ColumnType method ID
jmethodID prepid; // The CreatePrepStmt method ID
jmethodID xpid; // The ExecutePrep method ID
jmethodID pcid; // The ClosePrepStmt method ID
jmethodID errid; // The GetErrmsg method ID
jmethodID objfldid; // The ObjectField method ID
jmethodID chrfldid; // The StringField method ID
jmethodID intfldid; // The IntField method ID
jmethodID dblfldid; // The DoubleField method ID
jmethodID fltfldid; // The FloatField method ID
jmethodID datfldid; // The DateField method ID
jmethodID timfldid; // The TimeField method ID
jmethodID tspfldid; // The TimestampField method ID
jmethodID bigfldid; // The BigintField method ID
PCSZ Msg;
char *m_Wrap;
#if 0
JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv *env; // Pointer to native interface
jclass jdi; // Pointer to the java wrapper class
jobject job; // The java wrapper class object
jmethodID errid; // The GetErrmsg method ID
#endif // 0
jmethodID xqid; // The ExecuteQuery method ID
jmethodID xuid; // The ExecuteUpdate method ID
jmethodID xid; // The Execute method ID
jmethodID grs; // The GetResult method ID
jmethodID readid; // The ReadNext method ID
jmethodID fetchid; // The Fetch method ID
jmethodID typid; // The ColumnType method ID
jmethodID prepid; // The CreatePrepStmt method ID
jmethodID xpid; // The ExecutePrep method ID
jmethodID pcid; // The ClosePrepStmt method ID
jmethodID objfldid; // The ObjectField method ID
jmethodID chrfldid; // The StringField method ID
jmethodID intfldid; // The IntField method ID
jmethodID dblfldid; // The DoubleField method ID
jmethodID fltfldid; // The FloatField method ID
jmethodID datfldid; // The DateField method ID
jmethodID timfldid; // The TimeField method ID
jmethodID tspfldid; // The TimestampField method ID
jmethodID bigfldid; // The BigintField method ID
// PCSZ Msg;
// PCSZ m_Wrap;
char m_IDQuoteChar[2];
PCSZ m_Pwd;
int m_Ncol;
int m_Aff;
int m_Rows;
int m_Fetch;
int m_RowsetSize;
jboolean m_Updatable;
jboolean m_Transact;
jboolean m_Scrollable;
bool m_Opened;
bool m_Full;
}; // end of JDBConn class definition

357
storage/connect/jmgfam.cpp Normal file
View File

@@ -0,0 +1,357 @@
/************ JMONGO FAM C++ Program Source Code File (.CPP) ***********/
/* PROGRAM NAME: jmgfam.cpp */
/* ------------- */
/* Version 1.0 */
/* */
/* COPYRIGHT: */
/* ---------- */
/* (C) Copyright to the author Olivier BERTRAND 20017 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
/* This program are the Java MongoDB access method classes. */
/* */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
#if defined(__WIN__)
//#include <io.h>
//#include <fcntl.h>
//#include <errno.h>
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
#else // !__WIN__
#if defined(UNIX) || defined(UNIV_LINUX)
//#include <errno.h>
#include <unistd.h>
//#if !defined(sun) // Sun has the ftruncate fnc.
//#define USETEMP // Force copy mode for DELETE
//#endif // !sun
#else // !UNIX
//#include <io.h>
#endif // !UNIX
//#include <fcntl.h>
#endif // !__WIN__
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/* filamtxt.h is header containing the file AM classes declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "filamtxt.h"
#include "tabdos.h"
#include "tabjson.h"
#include "jmgfam.h"
#if defined(UNIX) || defined(UNIV_LINUX)
#include "osutil.h"
//#define _fileno fileno
//#define _O_RDONLY O_RDONLY
#endif
/* --------------------------- Class JMGFAM -------------------------- */
/***********************************************************************/
/* Constructors. */
/***********************************************************************/
JMGFAM::JMGFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
{
Jcp = NULL;
//Client = NULL;
//Database = NULL;
//Collection = NULL;
//Cursor = NULL;
//Query = NULL;
//Opts = NULL;
Ops.Driver = tdp->Schema;
Ops.Url = tdp->Uri;
Ops.User = NULL;
Ops.Pwd = NULL;
Ops.Scrollable = false;
Ops.Fsize = 0;
Ops.Version = tdp->Version;
To_Fbt = NULL;
Mode = MODE_ANY;
Uristr = tdp->Uri;
Db_name = tdp->Schema;
Coll_name = tdp->Collname;
Options = tdp->Options;
Filter = tdp->Filter;
Wrapname = tdp->Wrapname;
Done = false;
Pipe = tdp->Pipe;
Version = tdp->Version;
Lrecl = tdp->Lrecl + tdp->Ending;
Curpos = 0;
} // end of JMGFAM standard constructor
JMGFAM::JMGFAM(PJMGFAM tdfp) : DOSFAM(tdfp)
{
//Client = tdfp->Client;
//Database = NULL;
//Collection = tdfp->Collection;
//Cursor = tdfp->Cursor;
//Query = tdfp->Query;
//Opts = tdfp->Opts;
Ops = tdfp->Ops;
To_Fbt = tdfp->To_Fbt;
Mode = tdfp->Mode;
Uristr = tdfp->Uristr;
Db_name = tdfp->Db_name;
Coll_name = tdfp->Coll_name;
Options = tdfp->Options;
Filter = NULL;
Wrapname = tdfp->Wrapname;
Done = tdfp->Done;
Pipe = tdfp->Pipe;
Version = tdfp->Version;
} // end of JMGFAM copy constructor
/***********************************************************************/
/* Reset: reset position values at the beginning of file. */
/***********************************************************************/
void JMGFAM::Reset(void)
{
TXTFAM::Reset();
Fpos = Tpos = Spos = 0;
} // end of Reset
/***********************************************************************/
/* MGO GetFileLength: returns file size in number of bytes. */
/***********************************************************************/
int JMGFAM::GetFileLength(PGLOBAL g)
{
return 0;
} // end of GetFileLength
/***********************************************************************/
/* Cardinality: returns table cardinality in number of rows. */
/* This function can be called with a null argument to test the */
/* availability of Cardinality implementation (1 yes, 0 no). */
/***********************************************************************/
int JMGFAM::Cardinality(PGLOBAL g)
{
if (!g)
return 1;
return (!Init(g)) ? Jcp->CollSize(g) : 0;
} // end of Cardinality
/***********************************************************************/
/* Note: This function is not really implemented yet. */
/***********************************************************************/
int JMGFAM::MaxBlkSize(PGLOBAL, int s)
{
return s;
} // end of MaxBlkSize
/***********************************************************************/
/* Init: initialize MongoDB processing. */
/***********************************************************************/
bool JMGFAM::Init(PGLOBAL g)
{
if (Done)
return false;
/*********************************************************************/
/* Open an JDBC connection for this table. */
/* Note: this may not be the proper way to do. Perhaps it is better */
/* to test whether a connection is already open for this datasource */
/* and if so to allocate just a new result set. But this only for */
/* drivers allowing concurency in getting results ??? */
/*********************************************************************/
if (!Jcp)
Jcp = new(g) JMgoConn(g, Coll_name, Wrapname);
else if (Jcp->IsOpen())
Jcp->Close();
if (Jcp->Connect(&Ops))
return true;
Done = true;
return false;
} // end of Init
/***********************************************************************/
/* OpenTableFile: Open a MongoDB table. */
/***********************************************************************/
bool JMGFAM::OpenTableFile(PGLOBAL g)
{
Mode = Tdbp->GetMode();
if (Pipe && Mode != MODE_READ) {
strcpy(g->Message, "Pipeline tables are read only");
return true;
} // endif Pipe
if (Init(g))
return true;
if (Jcp->GetMethodId(g, Mode))
return true;
if (Mode == MODE_DELETE && !Tdbp->GetNext()) {
// Delete all documents
if (!Jcp->MakeCursor(g, Tdbp, "all", Filter, false))
if (Jcp->DocDelete(g, true) == RC_OK)
return false;
return true;
} // endif Mode
if (Mode == MODE_INSERT)
Jcp->MakeColumnGroups(g, Tdbp);
if (Mode != MODE_UPDATE)
return Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe);
return false;
} // end of OpenTableFile
/***********************************************************************/
/* GetRowID: return the RowID of last read record. */
/***********************************************************************/
int JMGFAM::GetRowID(void)
{
return Rows;
} // end of GetRowID
/***********************************************************************/
/* GetPos: return the position of last read record. */
/***********************************************************************/
int JMGFAM::GetPos(void)
{
return Fpos;
} // end of GetPos
/***********************************************************************/
/* GetNextPos: return the position of next record. */
/***********************************************************************/
int JMGFAM::GetNextPos(void)
{
return Fpos; // TODO
} // end of GetNextPos
/***********************************************************************/
/* SetPos: Replace the table at the specified position. */
/***********************************************************************/
bool JMGFAM::SetPos(PGLOBAL g, int pos)
{
Fpos = pos;
Placed = true;
return false;
} // end of SetPos
/***********************************************************************/
/* Record file position in case of UPDATE or DELETE. */
/***********************************************************************/
bool JMGFAM::RecordPos(PGLOBAL g)
{
strcpy(g->Message, "JMGFAM::RecordPos NIY");
return true;
} // end of RecordPos
/***********************************************************************/
/* Initialize Fpos and the current position for indexed DELETE. */
/***********************************************************************/
int JMGFAM::InitDelete(PGLOBAL g, int fpos, int spos)
{
strcpy(g->Message, "JMGFAM::InitDelete NIY");
return RC_FX;
} // end of InitDelete
/***********************************************************************/
/* Skip one record in file. */
/***********************************************************************/
int JMGFAM::SkipRecord(PGLOBAL g, bool header)
{
return RC_OK; // Dummy
} // end of SkipRecord
/***********************************************************************/
/* ReadBuffer: Get next document from a collection. */
/***********************************************************************/
int JMGFAM::ReadBuffer(PGLOBAL g)
{
int rc = RC_FX;
if (!Curpos && Mode == MODE_UPDATE)
if (Jcp->MakeCursor(g, Tdbp, Options, Filter, Pipe))
return RC_FX;
if (++CurNum >= Rbuf) {
Rbuf = Jcp->Fetch();
Curpos++;
CurNum = 0;
} // endif CurNum
if (Rbuf > 0) {
PSZ str = Jcp->GetDocument();
if (str) {
if (trace == 1)
htrc("%s\n", str);
strncpy(Tdbp->GetLine(), str, Lrecl);
rc = RC_OK;
} else
strcpy(g->Message, "Null document");
} else if (!Rbuf)
rc = RC_EF;
return rc;
} // end of ReadBuffer
/***********************************************************************/
/* WriteBuffer: File write routine for MGO access method. */
/***********************************************************************/
int JMGFAM::WriteBuffer(PGLOBAL g)
{
int rc = RC_OK;
if (Mode == MODE_INSERT) {
rc = Jcp->DocWrite(g);
} else if (Mode == MODE_DELETE) {
rc = Jcp->DocDelete(g, false);
} else if (Mode == MODE_UPDATE) {
rc = Jcp->DocUpdate(g, Tdbp);
} // endif Mode
return rc;
} // end of WriteBuffer
/***********************************************************************/
/* Data Base delete line routine for MGO and BLK access methods. */
/***********************************************************************/
int JMGFAM::DeleteRecords(PGLOBAL g, int irc)
{
return (irc == RC_OK) ? WriteBuffer(g) : RC_OK;
} // end of DeleteRecords
/***********************************************************************/
/* Table file close routine for MGO access method. */
/***********************************************************************/
void JMGFAM::CloseTableFile(PGLOBAL g, bool)
{
Jcp->Close();
Done = false;
} // end of CloseTableFile
/***********************************************************************/
/* Rewind routine for MGO access method. */
/***********************************************************************/
void JMGFAM::Rewind(void)
{
Jcp->Rewind();
} // end of Rewind

79
storage/connect/jmgfam.h Normal file
View File

@@ -0,0 +1,79 @@
/************** MongoFam H Declares Source Code File (.H) **************/
/* Name: jmgfam.h Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the JAVA MongoDB access method classes declares */
/***********************************************************************/
#pragma once
/***********************************************************************/
/* Include MongoDB library header files. */
/***********************************************************************/
#include "block.h"
//#include "mongo.h"
#include "jmgoconn.h"
typedef class JMGFAM *PJMGFAM;
typedef class MGODEF *PMGODEF;
/***********************************************************************/
/* This is the Java MongoDB Access Method class declaration. */
/***********************************************************************/
class DllExport JMGFAM : public DOSFAM {
friend void mongo_init(bool);
public:
// Constructor
JMGFAM(PJDEF tdp);
JMGFAM(PJMGFAM txfp);
// Implementation
virtual AMT GetAmType(void) { return TYPE_AM_MGO; }
virtual bool GetUseTemp(void) { return false; }
virtual int GetPos(void);
virtual int GetNextPos(void);
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) JMGFAM(this); }
void SetLrecl(int lrecl) { Lrecl = lrecl; }
// Methods
virtual void Reset(void);
virtual int GetFileLength(PGLOBAL g);
virtual int Cardinality(PGLOBAL g);
virtual int MaxBlkSize(PGLOBAL g, int s);
virtual bool AllocateBuffer(PGLOBAL g) { return false; }
virtual int GetRowID(void);
virtual bool RecordPos(PGLOBAL g);
virtual bool SetPos(PGLOBAL g, int recpos);
virtual int SkipRecord(PGLOBAL g, bool header);
virtual bool OpenTableFile(PGLOBAL g);
virtual int ReadBuffer(PGLOBAL g);
virtual int WriteBuffer(PGLOBAL g);
virtual int DeleteRecords(PGLOBAL g, int irc);
virtual void CloseTableFile(PGLOBAL g, bool abort);
virtual void Rewind(void);
protected:
virtual bool OpenTempFile(PGLOBAL g) { return false; }
virtual bool MoveIntermediateLines(PGLOBAL g, bool *b) { return false; }
virtual int RenameTempFile(PGLOBAL g) { return RC_OK; }
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
bool Init(PGLOBAL g);
//bool MakeCursor(PGLOBAL g);
// Members
JMgoConn *Jcp; // Points to a Mongo connection class
JDBCPARM Ops; // Additional parameters
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
PCSZ Uristr;
PCSZ Db_name;
PCSZ Coll_name;
PCSZ Options;
PCSZ Filter;
PSZ Wrapname;
bool Done; // Init done
bool Pipe;
int Version;
int Curpos; // Cursor position of last fetch
}; // end of class JMGFAM

View File

@@ -0,0 +1,813 @@
/************ JMgoConn C++ Functions Source Code File (.CPP) ***********/
/* Name: JMgoConn.CPP Version 1.1 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the MongoDB Java connection classes functions. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
/***********************************************************************/
/* Required objects includes. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "colblk.h"
#include "xobject.h"
#include "xtable.h"
#include "filter.h"
#include "jmgoconn.h"
#define nullptr 0
bool IsNum(PSZ s);
/* --------------------------- Class JNCOL --------------------------- */
/***********************************************************************/
/* Add a column in the column list. */
/***********************************************************************/
void JNCOL::AddCol(PGLOBAL g, PCOL colp, PSZ jp)
{
char *p;
PJKC kp, kcp;
if ((p = strchr(jp, '.'))) {
PJNCOL icp;
*p++ = 0;
for (kp = Klist; kp; kp = kp->Next)
if (kp->Jncolp && !strcmp(jp, kp->Key))
break;
if (!kp) {
icp = new(g) JNCOL(IsNum(p));
kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL));
kcp->Next = NULL;
kcp->Jncolp = icp;
kcp->Colp = NULL;
if (Array) {
kcp->Key = NULL;
kcp->N = atoi(p);
} else {
kcp->Key = PlugDup(g, jp);
kcp->N = 0;
} // endif Array
if (Klist) {
for (kp = Klist; kp->Next; kp = kp->Next);
kp->Next = kcp;
} else
Klist = kcp;
} else
icp = kp->Jncolp;
*(p - 1) = '.';
icp->AddCol(g, colp, p);
} else {
kcp = (PJKC)PlugSubAlloc(g, NULL, sizeof(JKCOL));
kcp->Next = NULL;
kcp->Jncolp = NULL;
kcp->Colp = colp;
if (Array) {
kcp->Key = NULL;
kcp->N = atoi(jp);
} else {
kcp->Key = jp;
kcp->N = 0;
} // endif Array
if (Klist) {
for (kp = Klist; kp->Next; kp = kp->Next);
kp->Next = kcp;
} else
Klist = kcp;
} // endif jp
} // end of AddCol
/***********************************************************************/
/* JMgoConn construction/destruction. */
/***********************************************************************/
JMgoConn::JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper)
: JAVAConn(g, wrapper)
{
CollName = collname;
readid = fetchid = getdocid = objfldid = fcollid = acollid =
mkdocid = docaddid = mkarid = araddid = insertid = updateid =
deleteid = gcollid = countid = rewindid = nullptr;
DiscFunc = "MongoDisconnect";
Fpc = NULL;
m_Fetch = 0;
m_Ncol = 0;
m_Version = 0;
} // end of JMgoConn
/***********************************************************************/
/* AddJars: add some jar file to the Class path. */
/***********************************************************************/
void JMgoConn::AddJars(PSTRG jpop, char sep)
{
#if defined(DEVELOPMENT)
if (m_Version == 2) {
jpop->Append(sep);
jpop->Append("C:/Eclipse/workspace/MongoWrap2/bin");
jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-2.13.3.jar");
} else {
jpop->Append(sep);
jpop->Append("C:/Eclipse/workspace/MongoWrap3/bin");
jpop->Append(sep);
jpop->Append("C:/mongo-java-driver/mongo-java-driver-3.4.2.jar");
} // endif m_Version
#endif // DEVELOPMENT
} // end of AddJars
/***********************************************************************/
/* Connect: connect to a data source. */
/***********************************************************************/
bool JMgoConn::Connect(PJPARM sop)
{
bool err = false;
jint rc;
jboolean brc;
jstring cln;
PGLOBAL& g = m_G;
m_Version = sop->Version;
/*******************************************************************/
/* Create or attach a JVM. */
/*******************************************************************/
if (Open(g))
return true;
/*******************************************************************/
/* Connect to MongoDB. */
/*******************************************************************/
jmethodID cid = nullptr;
if (gmID(g, cid, "MongoConnect", "([Ljava/lang/String;)I"))
return true;
// Build the java string array
jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4
env->FindClass("java/lang/String"), NULL); // Strings
//m_Scrollable = sop->Scrollable;
//m_RowsetSize = sop->Fsize;
// change some elements
if (sop->Driver)
env->SetObjectArrayElement(parms, 0, env->NewStringUTF(sop->Url));
if (sop->Url)
env->SetObjectArrayElement(parms, 1, env->NewStringUTF(sop->Driver));
if (sop->User)
env->SetObjectArrayElement(parms, 2, env->NewStringUTF(sop->User));
if (sop->Pwd)
env->SetObjectArrayElement(parms, 3, env->NewStringUTF(sop->Pwd));
// call method
rc = env->CallIntMethod(job, cid, parms);
err = Check(rc);
env->DeleteLocalRef(parms); // Not used anymore
if (err) {
sprintf(g->Message, "Connecting: %s rc=%d", Msg, (int)rc);
return true;
} // endif Msg
/*********************************************************************/
/* Get the collection. */
/*********************************************************************/
if (gmID(g, gcollid, "GetCollection", "(Ljava/lang/String;)Z"))
return true;
cln = env->NewStringUTF(CollName);
brc = env->CallBooleanMethod(job, gcollid, cln);
env->DeleteLocalRef(cln);
if (Check(brc ? -1 : 0)) {
sprintf(g->Message, "GetCollection: %s", Msg);
return true;
} // endif Msg
m_Connected = true;
return false;
} // end of Connect
/***********************************************************************/
/* CollSize: returns the number of documents in the collection. */
/***********************************************************************/
int JMgoConn::CollSize(PGLOBAL g)
{
if (!gmID(g, countid, "GetCollSize", "()J")) {
jlong card = env->CallLongMethod(job, countid);
return (int)card;
} else
return 2; // Make MariaDB happy
} // end of CollSize
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
bool JMgoConn::MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options,
PCSZ filter, bool pipe)
{
const char *p;
bool b = false, id = (tdbp->GetMode() != MODE_READ), all = false;
uint len;
PCOL cp;
PSZ jp;
PCSZ op = NULL, sf = NULL, Options = options;
PSTRG s = NULL;
if (Options && !stricmp(Options, "all")) {
Options = NULL;
all = true;
} // endif Options
for (cp = tdbp->GetColumns(); cp; cp = cp->GetNext())
if (!strcmp(cp->GetName(), "_id"))
id = true;
else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && (!Options || pipe))
all = true;
if (pipe && Options) {
if (trace)
htrc("Pipeline: %s\n", Options);
p = strrchr(Options, ']');
if (!p) {
strcpy(g->Message, "Missing ] in pipeline");
return true;
} else
*(char*)p = 0;
s = new(g) STRING(g, 1023, (PSZ)Options);
if (tdbp->GetFilter()) {
s->Append(",{\"$match\":");
if (tdbp->GetFilter()->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return NULL;
} else
s->Append('}');
tdbp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
if (!all && tdbp->GetColumns()) {
// Project list
len = s->GetLength();
s->Append(",{\"$project\":{\"");
if (!id)
s->Append("_id\":0,\"");
for (PCOL cp = tdbp->GetColumns(); cp; cp = cp->GetNext()) {
if (b)
s->Append(",\"");
else
b = true;
if ((jp = cp->GetJpath(g, true)))
s->Append(jp);
else {
s->Truncate(len);
goto nop;
} // endif Jpath
s->Append("\":1");
} // endfor cp
s->Append("}}");
} // endif all
nop:
s->Append("]}");
s->Resize(s->GetLength() + 1);
*(char*)p = ']'; // Restore Colist for discovery
p = s->GetStr();
if (trace)
htrc("New Pipeline: %s\n", p);
return AggregateCollection(p);
} else {
if (filter || tdbp->GetFilter()) {
if (trace) {
if (filter)
htrc("Filter: %s\n", filter);
if (tdbp->GetFilter()) {
char buf[512];
tdbp->GetFilter()->Prints(g, buf, 511);
htrc("To_Filter: %s\n", buf);
} // endif To_Filter
} // endif trace
s = new(g) STRING(g, 1023, (PSZ)filter);
len = s->GetLength();
if (tdbp->GetFilter()) {
if (filter)
s->Append(',');
if (tdbp->GetFilter()->MakeSelector(g, s)) {
strcpy(g->Message, "Failed making selector");
return NULL;
} // endif Selector
tdbp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
if (trace)
htrc("selector: %s\n", s->GetStr());
s->Resize(s->GetLength() + 1);
sf = PlugDup(g, s->GetStr());
} // endif Filter
if (!all) {
if (Options && *Options) {
if (trace)
htrc("options=%s\n", Options);
op = Options;
} else if (tdbp->GetColumns()) {
// Projection list
if (s)
s->Set("{\"");
else
s = new(g) STRING(g, 511, "{\"");
if (!id)
s->Append("_id\":0,\"");
for (PCOL cp = tdbp->GetColumns(); cp; cp = cp->GetNext()) {
if (b)
s->Append(",\"");
else
b = true;
if ((jp = cp->GetJpath(g, true)))
s->Append(jp);
else {
// Can this happen?
htrc("Fail getting projection path of %s\n", cp->GetName());
goto nope;
} // endif Jpath
s->Append("\":1");
} // endfor cp
s->Append("}");
s->Resize(s->GetLength() + 1);
op = s->GetStr();
} else {
// count(*) ?
op = "{\"_id\":1}";
} // endif Options
} // endif all
nope:
return FindCollection(sf, op);
} // endif Pipe
} // end of MakeCursor
/***********************************************************************/
/* Find a collection and make cursor. */
/***********************************************************************/
bool JMgoConn::FindCollection(PCSZ query, PCSZ proj)
{
bool rc = true;
jboolean brc;
jstring qry = nullptr, prj = nullptr;
PGLOBAL& g = m_G;
// Get the methods used to execute a query and get the result
if (!gmID(g, fcollid, "FindColl", "(Ljava/lang/String;Ljava/lang/String;)Z")) {
if (query)
qry = env->NewStringUTF(query);
if (proj)
prj = env->NewStringUTF(proj);
brc = env->CallBooleanMethod(job, fcollid, qry, prj);
if (!Check(brc ? -1 : 0)) {
rc = false;
} else
sprintf(g->Message, "FindColl: %s", Msg);
if (query)
env->DeleteLocalRef(qry);
if (proj)
env->DeleteLocalRef(prj);
} // endif xqid
return rc;
} // end of FindCollection
/***********************************************************************/
/* Find a collection and make cursor. */
/***********************************************************************/
bool JMgoConn::AggregateCollection(PCSZ pipeline)
{
bool rc = true;
jboolean brc;
jstring pip = nullptr;
PGLOBAL& g = m_G;
// Get the methods used to execute a query and get the result
if (!gmID(g, acollid, "AggregateColl", "(Ljava/lang/String;)Z")) {
pip = env->NewStringUTF(pipeline);
brc = env->CallBooleanMethod(job, acollid, pip);
if (!Check(brc ? -1 : 0)) {
rc = false;
} else
sprintf(g->Message, "AggregateColl: %s", Msg);
env->DeleteLocalRef(pip);
} // endif acollid
return rc;
} // end of AggregateCollection
/***********************************************************************/
/* Fetch next row. */
/***********************************************************************/
int JMgoConn::Fetch(int pos)
{
jint rc = JNI_ERR;
PGLOBAL& g = m_G;
//if (m_Full) // Result set has one row
// return 1;
//if (pos) {
// if (!m_Scrollable) {
// strcpy(g->Message, "Cannot fetch(pos) if FORWARD ONLY");
// return rc;
// } else if (gmID(m_G, fetchid, "Fetch", "(I)Z"))
// return rc;
// if (env->CallBooleanMethod(job, fetchid, pos))
// rc = m_Rows;
//} else {
if (gmID(g, readid, "ReadNext", "()I"))
return (int)rc;
rc = env->CallIntMethod(job, readid);
if (!Check(rc)) {
//if (rc == 0)
// m_Full = (m_Fetch == 1);
//else
// m_Fetch++;
m_Ncol = (int)rc;
rc = MY_MIN(rc, 1);
m_Rows += rc;
} else
sprintf(g->Message, "Fetch: %s", Msg);
//} // endif pos
return rc;
} // end of Fetch
/***********************************************************************/
/* Get the Json string of the current document. */
/***********************************************************************/
PSZ JMgoConn::GetDocument(void)
{
PGLOBAL& g = m_G;
PSZ doc = NULL;
jstring jdc;
if (!gmID(g, getdocid, "GetDoc", "()Ljava/lang/String;")) {
jdc = (jstring)env->CallObjectMethod(job, getdocid);
if (jdc)
doc = (PSZ)env->GetStringUTFChars(jdc, (jboolean)false);
} // endif getdocid
return doc;
} // end of GetDocument
/***********************************************************************/
/* Group columns for inserting or updating. */
/***********************************************************************/
void JMgoConn::MakeColumnGroups(PGLOBAL g, PTDB tdbp)
{
Fpc = new(g) JNCOL(false);
for (PCOL colp = tdbp->GetColumns(); colp; colp = colp->GetNext())
if (!colp->IsSpecial())
Fpc->AddCol(g, colp, colp->GetJpath(g, false));
} // end of MakeColumnGroups
/***********************************************************************/
/* Get additional method ID. */
/***********************************************************************/
bool JMgoConn::GetMethodId(PGLOBAL g, MODE mode)
{
if (mode == MODE_UPDATE) {
if (gmID(g, mkdocid, "MakeDocument", "()Ljava/lang/Object;"))
return true;
if (gmID(g, docaddid, "DocAdd",
"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"))
return true;
if (gmID(g, updateid, "CollUpdate", "(Ljava/lang/Object;)J"))
return true;
} else if (mode == MODE_INSERT) {
if (gmID(g, mkdocid, "MakeDocument", "()Ljava/lang/Object;"))
return true;
if (gmID(g, docaddid, "DocAdd",
"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Z"))
return true;
if (gmID(g, mkarid, "MakeArray", "()Ljava/lang/Object;"))
return true;
if (gmID(g, araddid, "ArrayAdd", "(Ljava/lang/Object;ILjava/lang/Object;)Z"))
return true;
if (gmID(g, insertid, "CollInsert", "(Ljava/lang/Object;)Z"))
return true;
} else if (mode == MODE_DELETE)
if (gmID(g, deleteid, "CollDelete", "(Z)J"))
return true;
return gmID(g, rewindid, "Rewind", "()Z");
} // end of GetMethodId
/***********************************************************************/
/* MakeObject. */
/***********************************************************************/
jobject JMgoConn::MakeObject(PGLOBAL g, PCOL colp, bool&error )
{
jclass cls;
jmethodID cns = nullptr; // Constructor
jobject val = nullptr;
PVAL valp = colp->GetValue();
error = false;
if (valp->IsNull())
return NULL;
try {
switch (valp->GetType()) {
case TYPE_STRING:
val = env->NewStringUTF(valp->GetCharValue());
break;
case TYPE_INT:
case TYPE_SHORT:
cls = env->FindClass("java/lang/Integer");
cns = env->GetMethodID(cls, "<init>", "(I)V");
val = env->NewObject(cls, cns, valp->GetIntValue());
break;
case TYPE_TINY:
cls = env->FindClass("java/lang/Boolean");
cns = env->GetMethodID(cls, "<init>", "(Z)V");
val = env->NewObject(cls, cns, (valp->GetIntValue() != 0));
break;
case TYPE_BIGINT:
cls = env->FindClass("java/lang/Long");
cns = env->GetMethodID(cls, "<init>", "(J)V");
val = env->NewObject(cls, cns, valp->GetBigintValue());
break;
case TYPE_DOUBLE:
cls = env->FindClass("java/lang/Double");
cns = env->GetMethodID(cls, "<init>", "(D)V");
val = env->NewObject(cls, cns, valp->GetFloatValue());
break;
default:
sprintf(g->Message, "Cannot make object from %d type", valp->GetType());
error = true;
break;
} // endswitch Type
} catch (...) {
sprintf(g->Message, "Cannot make object from %s value", colp->GetName());
error = true;
} // end try/catch
return val;
} // end of MakeObject
/***********************************************************************/
/* MakeDoc. */
/***********************************************************************/
jobject JMgoConn::MakeDoc(PGLOBAL g, PJNCOL jcp)
{
bool error = false;
jobject parent, child, val;
jstring jkey;
if (jcp->Array)
parent = env->CallObjectMethod(job, mkarid);
else
parent = env->CallObjectMethod(job, mkdocid);
for (PJKC kp = jcp->Klist; kp; kp = kp->Next)
if (kp->Jncolp) {
if (!(child = MakeDoc(g, kp->Jncolp)))
return NULL;
if (!jcp->Array) {
jkey = env->NewStringUTF(kp->Key);
if (env->CallBooleanMethod(job, docaddid, parent, jkey, child))
return NULL;
env->DeleteLocalRef(jkey);
} else
if (env->CallBooleanMethod(job, araddid, parent, kp->N, child))
return NULL;
} else {
if (!(val = MakeObject(g, kp->Colp, error))) {
if (error)
return NULL;
} else if (!jcp->Array) {
jkey = env->NewStringUTF(kp->Key);
if (env->CallBooleanMethod(job, docaddid, parent, jkey, val))
return NULL;
env->DeleteLocalRef(jkey);
} else if (env->CallBooleanMethod(job, araddid, parent, kp->N, val)) {
if (Check(-1))
sprintf(g->Message, "ArrayAdd: %s", Msg);
else
sprintf(g->Message, "ArrayAdd: unknown error");
return NULL;
} // endif ArrayAdd
} // endif Jncolp
return parent;
} // end of MakeDoc
/***********************************************************************/
/* Insert a new document in the collation. */
/***********************************************************************/
int JMgoConn::DocWrite(PGLOBAL g)
{
jobject doc;
if (!Fpc || !(doc = MakeDoc(g, Fpc)))
return RC_FX;
if (env->CallBooleanMethod(job, insertid, doc)) {
if (Check(-1))
sprintf(g->Message, "CollInsert: %s", Msg);
else
sprintf(g->Message, "CollInsert: unknown error");
return RC_FX;
} // endif Insert
return RC_OK;
} // end of DocWrite
/***********************************************************************/
/* Update the current document from the collection. */
/***********************************************************************/
int JMgoConn::DocUpdate(PGLOBAL g, PTDB tdbp)
{
int rc = RC_OK;
bool error;
PCOL colp;
jstring jkey;
jobject val, upd, updlist = env->CallObjectMethod(job, mkdocid);
// Make the list of changes to do
for (colp = tdbp->GetSetCols(); colp; colp = colp->GetNext()) {
jkey = env->NewStringUTF(colp->GetJpath(g, false));
val = MakeObject(g, colp, error);
if (error)
return RC_FX;
if (env->CallBooleanMethod(job, docaddid, updlist, jkey, val))
return NULL;
env->DeleteLocalRef(jkey);
} // endfor colp
// Make the update parameter
upd = env->CallObjectMethod(job, mkdocid);
jkey = env->NewStringUTF("$set");
if (env->CallBooleanMethod(job, docaddid, upd, jkey, updlist))
return NULL;
env->DeleteLocalRef(jkey);
jlong ar = env->CallLongMethod(job, updateid, upd);
if (trace)
htrc("DocUpdate: ar = %ld\n", ar);
if (Check((int)ar)) {
sprintf(g->Message, "CollUpdate: %s", Msg);
rc = RC_FX;
} // endif ar
return rc;
} // end of DocUpdate
/***********************************************************************/
/* Remove all or only the current document from the collection. */
/***********************************************************************/
int JMgoConn::DocDelete(PGLOBAL g, bool all)
{
int rc = RC_OK;
jlong ar = env->CallLongMethod(job, deleteid, all);
if (trace)
htrc("DocDelete: ar = %ld\n", ar);
if (Check((int)ar)) {
sprintf(g->Message, "CollDelete: %s", Msg);
rc = RC_FX;
} // endif ar
return rc;
} // end of DocDelete
/***********************************************************************/
/* Rewind the collection. */
/***********************************************************************/
bool JMgoConn::Rewind(void)
{
return env->CallBooleanMethod(job, rewindid);
} // end of Rewind
/***********************************************************************/
/* Retrieve the column string value from the document. */
/***********************************************************************/
PSZ JMgoConn::GetColumnValue(PSZ path)
{
PGLOBAL& g = m_G;
PSZ fld = NULL;
jstring fn, jn = nullptr;
if (!path || (jn = env->NewStringUTF(path)) == nullptr) {
sprintf(g->Message, "Fail to allocate jstring %s", SVP(path));
throw (int)TYPE_AM_MGO;
} // endif name
if (!gmID(g, objfldid, "GetField", "(Ljava/lang/String;)Ljava/lang/String;")) {
fn = (jstring)env->CallObjectMethod(job, objfldid, jn);
if (fn)
fld = (PSZ)env->GetStringUTFChars(fn, (jboolean)false);
} // endif objfldid
return fld;
} // end of GetColumnValue

113
storage/connect/jmgoconn.h Normal file
View File

@@ -0,0 +1,113 @@
/***********************************************************************/
/* JMgoConn.h : header file for the MongoDB connection classes. */
/***********************************************************************/
/***********************************************************************/
/* Java interface. */
/***********************************************************************/
#include "javaconn.h"
// Java connection to a MongoDB data source
class TDBJMG;
class JMGCOL;
/***********************************************************************/
/* Include MongoDB library header files. */
/***********************************************************************/
typedef class JNCOL *PJNCOL;
typedef class MGODEF *PMGODEF;
typedef class TDBJMG *PTDBJMG;
typedef class JMGCOL *PJMGCOL;
typedef struct JKCOL {
JKCOL *Next;
PJNCOL Jncolp;
PCOL Colp;
char *Key;
int N;
} *PJKC;
/***********************************************************************/
/* Used when inserting values in a MongoDB collection. */
/***********************************************************************/
class JNCOL : public BLOCK {
public:
// Constructor
JNCOL(bool ar) { Klist = NULL; Array = ar; }
// Methods
void AddCol(PGLOBAL g, PCOL colp, PSZ jp);
//Members
PJKC Klist;
bool Array;
}; // end of JNCOL;
/***********************************************************************/
/* JMgoConn class. */
/***********************************************************************/
class JMgoConn : public JAVAConn {
friend class TDBJMG;
friend class JMGDISC;
//friend class TDBXJDC;
//friend PQRYRES GetColumnInfo(PGLOBAL, char*&, char *, int, PVBLK&);
private:
JMgoConn(); // Standard (unused) constructor
public:
// Constructor
JMgoConn(PGLOBAL g, PCSZ collname, PCSZ wrapper);
// Implementation
public:
virtual void AddJars(PSTRG jpop, char sep);
virtual bool Connect(PJPARM sop);
virtual bool MakeCursor(PGLOBAL g, PTDB tdbp, PCSZ options, PCSZ filter, bool pipe);
// PQRYRES AllocateResult(PGLOBAL g, TDBEXT *tdbp, int n);
// Attributes
public:
// virtual int GetMaxValue(int infotype);
public:
// Operations
virtual int Fetch(int pos = 0);
virtual PSZ GetColumnValue(PSZ name);
int CollSize(PGLOBAL g);
bool FindCollection(PCSZ query, PCSZ proj);
bool AggregateCollection(PCSZ pipeline);
void MakeColumnGroups(PGLOBAL g, PTDB tdbp);
bool GetMethodId(PGLOBAL g, MODE mode);
jobject MakeObject(PGLOBAL g, PCOL colp, bool& error);
jobject MakeDoc(PGLOBAL g, PJNCOL jcp);
int DocWrite(PGLOBAL g);
int DocUpdate(PGLOBAL g, PTDB tdbp);
int DocDelete(PGLOBAL g, bool all);
bool Rewind(void);
PSZ GetDocument(void);
protected:
// Members
PCSZ CollName; // The collation name
jmethodID gcollid; // The GetCollection method ID
jmethodID countid; // The GetCollSize method ID
jmethodID fcollid; // The FindColl method ID
jmethodID acollid; // The AggregateColl method ID
jmethodID readid; // The ReadNext method ID
jmethodID fetchid; // The Fetch method ID
jmethodID rewindid; // The Rewind method ID
jmethodID getdocid; // The GetDoc method ID
jmethodID objfldid; // The ObjectField method ID
jmethodID mkdocid; // The MakeDocument method ID
jmethodID docaddid; // The DocAdd method ID
jmethodID mkarid; // The MakeArray method ID
jmethodID araddid; // The ArrayAdd method ID
jmethodID insertid; // The CollInsert method ID
jmethodID updateid; // The CollUpdate method ID
jmethodID deleteid; // The CollDelete method ID
PJNCOL Fpc; // To JNCOL classes
int m_Fetch;
int m_Ncol;
int m_Version; // Java driver version (2 or 3)
}; // end of JMgoConn class definition

View File

@@ -1,5 +1,5 @@
/*************** json CPP Declares Source Code File (.H) ***************/
/* Name: json.cpp Version 1.3 */
/* Name: json.cpp Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
/* */
@@ -53,6 +53,8 @@ void trans_func(unsigned int u, _EXCEPTION_POINTERS* pExp)
char *GetExceptionDesc(PGLOBAL g, unsigned int e);
#endif // SE_CATCH
char *GetJsonNull(void);
/***********************************************************************/
/* IsNum: check whether this string is all digits. */
/***********************************************************************/
@@ -537,7 +539,7 @@ PVAL ParseNumeric(PGLOBAL g, int& i, STRG& src)
if (!has_e)
goto err;
// passthru
// fall through
case '-':
if (found_digit)
goto err;
@@ -827,7 +829,7 @@ bool JOUTSTR::Escape(const char *s)
case '\r':
case '\b':
case '\f': WriteChr('\\');
// passthru
// fall through
default:
WriteChr(s[i]);
break;
@@ -963,6 +965,25 @@ return false;
/* -------------------------- Class JOBJECT -------------------------- */
/***********************************************************************/
/* Return the number of pairs in this object. */
/***********************************************************************/
int JOBJECT::GetSize(bool b)
{
if (b) {
// Return only non null pairs
int n = 0;
for (PJPR jpp = First; jpp; jpp = jpp->Next)
if (jpp->Val && !jpp->Val->IsNull())
n++;
return n;
} else
return Size;
} // end of GetSize
/***********************************************************************/
/* Add a new pair to an Object. */
/***********************************************************************/
@@ -1046,7 +1067,7 @@ PSZ JOBJECT::GetText(PGLOBAL g, PSZ text)
PlugSubAlloc(g, NULL, strlen(text) + 1);
return text + n;
} // end of GetValue;
} // end of GetText;
/***********************************************************************/
/* Merge two objects. */
@@ -1087,7 +1108,7 @@ void JOBJECT::SetValue(PGLOBAL g, PJVAL jvp, PCSZ key)
} // end of SetValue
/***********************************************************************/
/* Delete a value corresponding to the given key. */
/* Delete a value corresponding to the given key. */
/***********************************************************************/
void JOBJECT::DeleteKey(PCSZ key)
{
@@ -1117,6 +1138,25 @@ bool JOBJECT::IsNull(void)
/* -------------------------- Class JARRAY --------------------------- */
/***********************************************************************/
/* Return the number of values in this object. */
/***********************************************************************/
int JARRAY::GetSize(bool b)
{
if (b) {
// Return only non null values
int n = 0;
for (PJVAL jvp = First; jvp; jvp = jvp->Next)
if (!jvp->IsNull())
n++;
return n;
} else
return Size;
} // end of GetSize
/***********************************************************************/
/* Make the array of values from the values list. */
/***********************************************************************/
@@ -1225,18 +1265,42 @@ bool JARRAY::SetValue(PGLOBAL g, PJVAL jvp, int n)
return false;
} // end of SetValue
/***********************************************************************/
/* Return the text corresponding to all values. */
/***********************************************************************/
PSZ JARRAY::GetText(PGLOBAL g, PSZ text)
{
int n;
PJVAL jp;
if (!text) {
text = (char*)PlugSubAlloc(g, NULL, 0);
text[0] = 0;
n = 1;
} else
n = 0;
for (jp = First; jp; jp = jp->Next)
jp->GetText(g, text);
if (n)
PlugSubAlloc(g, NULL, strlen(text) + 1);
return text + n;
} // end of GetText;
/***********************************************************************/
/* Delete a Value from the Arrays Value list. */
/***********************************************************************/
bool JARRAY::DeleteValue(int n)
{
PJVAL jvp = GetValue(n);
PJVAL jvp = GetValue(n);
if (jvp) {
jvp->Del = true;
return false;
} else
return true;
if (jvp) {
jvp->Del = true;
return false;
} else
return true;
} // end of DeleteValue
@@ -1286,7 +1350,7 @@ JTYP JVALUE::GetValType(void)
else if (Value)
return (JTYP)Value->GetType();
else
return (JTYP)TYPE_VOID;
return TYPE_NULL;
} // end of GetValType
@@ -1350,7 +1414,7 @@ PSZ JVALUE::GetString(void)
/***********************************************************************/
PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
{
if (Jsp && Jsp->GetType() == TYPE_JOB)
if (Jsp)
return Jsp->GetText(g, text);
char buf[32];
@@ -1358,8 +1422,8 @@ PSZ JVALUE::GetText(PGLOBAL g, PSZ text)
if (s)
strcat(strcat(text, " "), s);
else
strcat(text, " <null>");
else if (GetJsonNull())
strcat(strcat(text, " "), GetJsonNull());
return text;
} // end of GetText

View File

@@ -13,7 +13,8 @@
#define X
#endif
enum JTYP {TYPE_STRG = TYPE_STRING,
enum JTYP {TYPE_NULL = TYPE_VOID,
TYPE_STRG = TYPE_STRING,
TYPE_DBL = TYPE_DOUBLE,
TYPE_BOOL = TYPE_TINY,
TYPE_BINT = TYPE_BIGINT,
@@ -146,6 +147,7 @@ class JSON : public BLOCK {
JSON(void) {Size = 0;}
int size(void) {return Size;}
virtual int GetSize(bool b) {return Size;}
virtual void Clear(void) {Size = 0;}
virtual JTYP GetType(void) {return TYPE_JSON;}
virtual JTYP GetValType(void) {X return TYPE_JSON;}
@@ -193,10 +195,11 @@ class JOBJECT : public JSON {
using JSON::GetValue;
using JSON::SetValue;
virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JOB;}
virtual PJPR GetFirst(void) {return First;}
virtual PJPR AddPair(PGLOBAL g, PCSZ key);
virtual int GetSize(bool b);
virtual PJPR AddPair(PGLOBAL g, PCSZ key);
virtual PJOB GetObject(void) {return this;}
virtual PJVAL GetValue(const char* key);
virtual PJAR GetKeyList(PGLOBAL g);
@@ -222,11 +225,13 @@ class JARRAY : public JSON {
using JSON::GetValue;
using JSON::SetValue;
virtual void Clear(void) {First = Last = NULL; Size = 0;}
virtual JTYP GetType(void) {return TYPE_JAR;}
virtual JTYP GetType(void) {return TYPE_JAR;}
virtual PJAR GetArray(void) {return this;}
PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
virtual int GetSize(bool b);
PJVAL AddValue(PGLOBAL g, PJVAL jvp = NULL, int *x = NULL);
virtual void InitArray(PGLOBAL g);
virtual PJVAL GetValue(int i);
virtual PSZ GetText(PGLOBAL g, PSZ text);
virtual bool Merge(PGLOBAL g, PJSON jsp);
virtual bool SetValue(PGLOBAL g, PJVAL jvp, int i);
virtual bool DeleteValue(int n);
@@ -246,20 +251,20 @@ class JARRAY : public JSON {
class JVALUE : public JSON {
friend class JARRAY;
friend class JSNX;
friend class JSONCOL;
friend PJVAL ParseValue(PGLOBAL, int&, STRG&, bool*);
friend bool SerializeValue(JOUT *, PJVAL);
public:
JVALUE(void) : JSON()
{Jsp = NULL; Value = NULL; Next = NULL; Del = false;}
JVALUE(void) : JSON() {Clear();}
JVALUE(PJSON jsp) : JSON()
{Jsp = jsp; Value = NULL; Next = NULL; Del = false;}
JVALUE(PGLOBAL g, PVAL valp);
{Jsp = jsp; Value = NULL; Next = NULL; Del = false; Size = 1;}
JVALUE(PGLOBAL g, PVAL valp);
JVALUE(PGLOBAL g, PCSZ strp);
using JSON::GetValue;
using JSON::SetValue;
virtual void Clear(void)
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 0;}
{Jsp = NULL; Value = NULL; Next = NULL; Del = false; Size = 1;}
virtual JTYP GetType(void) {return TYPE_JVAL;}
virtual JTYP GetValType(void);
virtual PJOB GetObject(void);

View File

@@ -1,5 +1,5 @@
/****************** jsonudf C++ Program Source Code File (.CPP) ******************/
/* PROGRAM NAME: jsonudf Version 1.5 */
/* PROGRAM NAME: jsonudf Version 1.6 */
/* (C) Copyright to the author Olivier BERTRAND 2015-2017 */
/* This program are the JSON User Defined Functions . */
/*********************************************************************************/
@@ -29,6 +29,7 @@
bool IsNum(PSZ s);
char *NextChr(PSZ s, char sep);
char *GetJsonNull(void);
uint GetJsonGrpSize(void);
static int IsJson(UDF_ARGS *args, uint i);
static PSZ MakePSZ(PGLOBAL g, UDF_ARGS *args, int i);
@@ -327,6 +328,8 @@ PVAL JSNX::MakeJson(PGLOBAL g, PJSON jsp)
void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
{
if (val) {
vp->SetNull(false);
if (Jb) {
vp->SetValue_psz(Serialize(g, val->GetJsp(), NULL, 0));
} else switch (val->GetValType()) {
@@ -347,11 +350,13 @@ void JSNX::SetJsonValue(PGLOBAL g, PVAL vp, PJVAL val, int n)
SetJsonValue(g, vp, val->GetArray()->GetValue(0), n);
break;
case TYPE_JOB:
// if (!vp->IsTypeNum() || !Strict) {
// if (!vp->IsTypeNum() || !Strict) {
vp->SetValue_psz(val->GetObject()->GetText(g, NULL));
break;
// } // endif Type
// } // endif Type
case TYPE_NULL:
vp->SetNull(true);
default:
vp->Reset();
} // endswitch Type
@@ -488,15 +493,16 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
JVALUE jval;
vp->Reset();
//ars = MY_MIN(Tjp->Limit, arp->size());
ars = arp->size();
for (i = 0; i < ars; i++) {
jvrp = arp->GetValue(i);
// do {
if (n < Nod - 1 && jvrp->GetJson()) {
// Tjp->NextSame = nextsame;
if (!jvrp->IsNull() || (op == OP_CNC && GetJsonNull())) {
if (jvrp->IsNull()) {
jvrp->Value = AllocateValue(g, GetJsonNull(), TYPE_STRING);
jvp = jvrp;
} else if (n < Nod - 1 && jvrp->GetJson()) {
jval.SetValue(GetColumnValue(g, jvrp->GetJson(), n + 1));
jvp = &jval;
} else
@@ -510,25 +516,25 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
if (!MulVal->IsZero()) {
switch (op) {
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
err = vp->Compute(g, val, 1, op);
} // endif CncVal
case OP_CNC:
if (Nodes[n].CncVal) {
val[0] = Nodes[n].CncVal;
err = vp->Compute(g, val, 1, op);
} // endif CncVal
val[0] = MulVal;
err = vp->Compute(g, val, 1, op);
break;
// case OP_NUM:
case OP_SEP:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, op);
val[0] = MulVal;
err = vp->Compute(g, val, 1, op);
break;
// case OP_NUM:
case OP_SEP:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, OP_ADD);
break;
default:
val[0] = Nodes[n].Valp;
val[1] = MulVal;
err = vp->Compute(g, val, 2, op);
} // endswitch Op
if (err)
@@ -536,7 +542,7 @@ PVAL JSNX::CalculateArray(PGLOBAL g, PJAR arp, int n)
} // endif Zero
// } while (Tjp->NextSame > nextsame);
} // endif jvrp
} // endfor i
@@ -1100,6 +1106,7 @@ inline void JsonMemSave(PGLOBAL g)
/*********************************************************************************/
inline void JsonFreeMem(PGLOBAL g)
{
g->Activityp = NULL;
PlugExit(g);
} /* end of JsonFreeMem */
@@ -1111,7 +1118,7 @@ static my_bool JsonInit(UDF_INIT *initid, UDF_ARGS *args,
unsigned long reslen, unsigned long memlen,
unsigned long more = 0)
{
PGLOBAL g = PlugInit(NULL, memlen + more);
PGLOBAL g = PlugInit(NULL, memlen + more + 500); // +500 to avoid CheckMem
if (!g) {
strcpy(message, "Allocation error");
@@ -1471,6 +1478,11 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n,
ml += g->More;
if (ml > g->Sarea_Size) {
#if !defined(DEVELOPMENT)
if (trace)
#endif
htrc("Freeing Sarea at %p size=%d\n", g->Sarea, g->Sarea_Size);
free(g->Sarea);
if (!(g->Sarea = PlugAllocMem(g, ml))) {
@@ -1814,7 +1826,7 @@ char *json_make_array(UDF_INIT *initid, UDF_ARGS *args, char *result,
return str;
} // end of json_make_array
void json_array_deinit(UDF_INIT* initid)
void json_make_array_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_make_array_deinit
@@ -2097,6 +2109,206 @@ void json_array_delete_deinit(UDF_INIT* initid)
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of json_array_delete_deinit
/*********************************************************************************/
/* Sum big integer values from a Json array. */
/*********************************************************************************/
my_bool jsonsum_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, more;
if (args->arg_count != 1) {
strcpy(message, "This function must have 1 argument");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen);
// TODO: calculate this
more = (IsJson(args, 0) != 3) ? 1000 : 0;
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonsum_int_init
long long jsonsum_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
long long n = 0LL;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Activityp) {
*is_null = 1;
return 0LL;
} else
return *(long long*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
if (!CheckMemory(g, initid, args, 1, false, false, true)) {
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JAR) {
PJAR arp = jvp->GetArray();
for (int i = 0; i < arp->size(); i++)
n += arp->GetValue(i)->GetBigint();
} else {
PUSH_WARNING("First argument target is not an array");
} // endif jvp
} else {
*error = 1;
n = -1LL;
} // end of CheckMemory
if (g->N) {
// Keep result of constant function
long long *np = (long long*)PlugSubAlloc(g, NULL, sizeof(long long));
*np = n;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
} // end of jsonsum_int
void jsonsum_int_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonsum_int_deinit
/*********************************************************************************/
/* Sum big integer values from a Json array. */
/*********************************************************************************/
my_bool jsonsum_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
unsigned long reslen, memlen, more;
if (args->arg_count != 1) {
strcpy(message, "This function must have 1 argument");
return true;
} else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) {
strcpy(message, "First argument must be a json item");
return true;
} else
CalcLen(args, false, reslen, memlen);
// TODO: calculate this
more = (IsJson(args, 0) != 3) ? 1000 : 0;
return JsonInit(initid, args, message, true, reslen, memlen, more);
} // end of jsonsum_real_init
double jsonsum_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double n = 0.0;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Activityp) {
*is_null = 1;
return 0.0;
} else
return *(double*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
if (!CheckMemory(g, initid, args, 1, false, false, true)) {
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JAR) {
PJAR arp = jvp->GetArray();
for (int i = 0; i < arp->size(); i++)
n += arp->GetValue(i)->GetFloat();
} else {
PUSH_WARNING("First argument target is not an array");
} // endif jvp
} else {
*error = 1;
n = -1.0;
} // end of CheckMemory
if (g->N) {
// Keep result of constant function
double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
*np = n;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
} // end of jsonsum_real
void jsonsum_real_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonsum_real_deinit
/*********************************************************************************/
/* Returns the average of big integer values from a Json array. */
/*********************************************************************************/
my_bool jsonavg_real_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
return jsonsum_real_init(initid, args, message);
} // end of jsonavg_real_init
double jsonavg_real(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
double n = 0.0;
PGLOBAL g = (PGLOBAL)initid->ptr;
if (g->N) {
if (!g->Activityp) {
*is_null = 1;
return 0.0;
} else
return *(double*)g->Activityp;
} else if (initid->const_item)
g->N = 1;
if (!CheckMemory(g, initid, args, 1, false, false, true)) {
PJVAL jvp = MakeValue(g, args, 0);
if (jvp && jvp->GetValType() == TYPE_JAR) {
PJAR arp = jvp->GetArray();
if (arp->size()) {
for (int i = 0; i < arp->size(); i++)
n += arp->GetValue(i)->GetFloat();
n /= arp->size();
} // endif size
} else {
PUSH_WARNING("First argument target is not an array");
} // endif jvp
} else {
*error = 1;
n = -1.0;
} // end of CheckMemory
if (g->N) {
// Keep result of constant function
double *np = (double*)PlugSubAlloc(g, NULL, sizeof(double));
*np = n;
g->Activityp = (PACTIVITY)np;
} // endif const_item
return n;
} // end of jsonavg_real
void jsonavg_real_deinit(UDF_INIT* initid)
{
JsonFreeMem((PGLOBAL)initid->ptr);
} // end of jsonavg_real_deinit
/*********************************************************************************/
/* Make a Json Object containing all the parameters. */
/*********************************************************************************/
@@ -2990,6 +3202,7 @@ char *jsonget_string(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {
@@ -3039,7 +3252,7 @@ my_bool jsonget_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
} // end of jsonget_int_init
long long jsonget_int(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error)
char *is_null, char *error)
{
char *p, *path;
long long n;
@@ -3330,6 +3543,7 @@ char *jsonlocate(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
@@ -3454,6 +3668,7 @@ char *json_locate_all(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
*error = 1;
path = NULL;
@@ -3728,6 +3943,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result,
} catch (int n) {
if (trace)
htrc("Exception %d: %s\n", n, g->Message);
PUSH_WARNING(g->Message);
str = NULL;
} catch (const char *msg) {

View File

@@ -53,6 +53,18 @@ extern "C" {
DllExport char *json_array_delete(UDF_EXEC_ARGS);
DllExport void json_array_delete_deinit(UDF_INIT*);
DllExport my_bool jsonsum_int_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport long long jsonsum_int(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonsum_int_deinit(UDF_INIT*);
DllExport my_bool jsonsum_real_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport double jsonsum_real(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonsum_real_deinit(UDF_INIT*);
DllExport my_bool jsonavg_real_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport double jsonavg_real(UDF_INIT*, UDF_ARGS*, char*, char*);
DllExport void jsonavg_real_deinit(UDF_INIT*);
DllExport my_bool json_make_object_init(UDF_INIT*, UDF_ARGS*, char*);
DllExport char *json_make_object(UDF_EXEC_ARGS);
DllExport void json_make_object_deinit(UDF_INIT*);

371
storage/connect/mongo.cpp Normal file
View File

@@ -0,0 +1,371 @@
/************** mongo C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: mongo Version 1.0 */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* These programs are the MGODEF class execution routines. */
/***********************************************************************/
/***********************************************************************/
/* Include relevant sections of the MariaDB header file. */
/***********************************************************************/
#include <my_global.h>
/***********************************************************************/
/* Include application header files: */
/* global.h is header containing all global declarations. */
/* plgdbsem.h is header containing the DB application declarations. */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#include "xtable.h"
#include "tabext.h"
#if defined(CMGO_SUPPORT)
#include "tabcmg.h"
#endif // MONGO_SUPPORT
#if defined(JDBC_SUPPORT)
#include "tabjmg.h"
#endif // JDBC_SUPPORT
#include "resource.h"
/***********************************************************************/
/* This should be an option. */
/***********************************************************************/
#define MAXCOL 200 /* Default max column nb in result */
#define TYPE_UNKNOWN 12 /* Must be greater than other types */
bool IsNum(PSZ s);
/***********************************************************************/
/* MGOColumns: construct the result blocks containing the description */
/* of all the columns of a document contained inside MongoDB. */
/***********************************************************************/
PQRYRES MGOColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt, bool info)
{
static int buftyp[] = {TYPE_STRING, TYPE_SHORT, TYPE_STRING, TYPE_INT,
TYPE_INT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING};
static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_TYPENAME, FLD_PREC,
FLD_LENGTH, FLD_SCALE, FLD_NULL, FLD_FORMAT};
unsigned int length[] = {0, 6, 8, 10, 10, 6, 6, 0};
int ncol = sizeof(buftyp) / sizeof(int);
int i, n = 0;
PBCOL bcp;
MGODISC *cmgd;
PQRYRES qrp;
PCOLRES crp;
if (info) {
length[0] = 128;
length[7] = 256;
goto skipit;
} // endif info
/*********************************************************************/
/* Open MongoDB. */
/*********************************************************************/
PCSZ drv = GetStringTableOption(g, topt, "Driver", NULL);
if (drv && toupper(*drv) == 'C') {
#if defined(CMGO_SUPPORT)
cmgd = new(g) CMGDISC(g, (int*)length);
#else
sprintf(g->Message, "Mongo %s Driver not available", "C");
goto err;
#endif
} else if (drv && toupper(*drv) == 'J') {
#if defined(JDBC_SUPPORT)
cmgd = new(g) JMGDISC(g, (int*)length);
#else
sprintf(g->Message, "Mongo %s Driver not available", "Java");
goto err;
#endif
} else { // Driver not specified
#if defined(CMGO_SUPPORT)
cmgd = new(g) CMGDISC(g, (int*)length);
#else
cmgd = new(g) JMGDISC(g, (int*)length);
#endif
} // endif drv
if ((n = cmgd->GetColumns(g, db, uri, topt)) < 0)
goto err;
skipit:
if (trace)
htrc("MGOColumns: n=%d len=%d\n", n, length[0]);
/*********************************************************************/
/* Allocate the structures used to refer to the result set. */
/*********************************************************************/
qrp = PlgAllocResult(g, ncol, n, IDS_COLUMNS + 3,
buftyp, fldtyp, length, false, false);
crp = qrp->Colresp->Next->Next->Next->Next->Next->Next;
crp->Name = "Nullable";
crp->Next->Name = "Bpath";
if (info || !qrp)
return qrp;
qrp->Nblin = n;
/*********************************************************************/
/* Now get the results into blocks. */
/*********************************************************************/
for (i = 0, bcp = cmgd->fbcp; bcp; i++, bcp = bcp->Next) {
if (bcp->Type == TYPE_UNKNOWN) // Void column
bcp->Type = TYPE_STRING;
crp = qrp->Colresp; // Column Name
crp->Kdata->SetValue(bcp->Name, i);
crp = crp->Next; // Data Type
crp->Kdata->SetValue(bcp->Type, i);
crp = crp->Next; // Type Name
crp->Kdata->SetValue(GetTypeName(bcp->Type), i);
crp = crp->Next; // Precision
crp->Kdata->SetValue(bcp->Len, i);
crp = crp->Next; // Length
crp->Kdata->SetValue(bcp->Len, i);
crp = crp->Next; // Scale (precision)
crp->Kdata->SetValue(bcp->Scale, i);
crp = crp->Next; // Nullable
crp->Kdata->SetValue(bcp->Cbn ? 1 : 0, i);
crp = crp->Next; // Field format
if (crp->Kdata)
crp->Kdata->SetValue(bcp->Fmt, i);
} // endfor i
/*********************************************************************/
/* Return the result pointer. */
/*********************************************************************/
return qrp;
err:
if (cmgd->tmgp)
cmgd->tmgp->CloseDB(g);
return NULL;
} // end of MGOColumns
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
MGODISC::MGODISC(PGLOBAL g, int *lg) {
length = lg;
fbcp = NULL;
pbcp = NULL;
tmgp = NULL;
drv = NULL;
i = ncol = lvl = 0;
all = false;
} // end of MGODISC constructor
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
int MGODISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt)
{
PCSZ level = GetStringTableOption(g, topt, "Level", NULL);
PMGODEF tdp;
if (level) {
lvl = atoi(level);
lvl = (lvl > 16) ? 16 : lvl;
} else
lvl = 0;
all = GetBooleanTableOption(g, topt, "Fullarray", false);
/*********************************************************************/
/* Open the MongoDB collection. */
/*********************************************************************/
tdp = new(g) MGODEF;
tdp->Uri = uri;
tdp->Driver = drv;
tdp->Tabname = GetStringTableOption(g, topt, "Name", NULL);
tdp->Tabname = GetStringTableOption(g, topt, "Tabname", tdp->Tabname);
tdp->Tabschema = GetStringTableOption(g, topt, "Dbname", db);
tdp->Base = GetIntegerTableOption(g, topt, "Base", 0) ? 1 : 0;
tdp->Colist = GetStringTableOption(g, topt, "Colist", "all");
tdp->Filter = GetStringTableOption(g, topt, "Filter", NULL);
tdp->Pipe = GetBooleanTableOption(g, topt, "Pipeline", false);
tdp->Version = GetIntegerTableOption(g, topt, "Version", 3);
tdp->Wrapname = (PSZ)GetStringTableOption(g, topt, "Wrapper",
(tdp->Version == 2) ? "Mongo2Interface" : "Mongo3Interface");
if (trace)
htrc("Uri %s coll=%s db=%s colist=%s filter=%s lvl=%d\n",
tdp->Uri, tdp->Tabname, tdp->Tabschema, tdp->Colist, tdp->Filter, lvl);
tmgp = tdp->GetTable(g, MODE_READ);
tmgp->SetMode(MODE_READ);
if (tmgp->OpenDB(g))
return -1;
bcol.Next = NULL;
bcol.Name = bcol.Fmt = NULL;
bcol.Type = TYPE_UNKNOWN;
bcol.Len = bcol.Scale = 0;
bcol.Found = true;
bcol.Cbn = false;
if (Init(g))
return -1;
/*********************************************************************/
/* Analyse the BSON tree and define columns. */
/*********************************************************************/
for (i = 1; ; i++) {
switch (tmgp->ReadDB(g)) {
case RC_EF:
return ncol;
case RC_FX:
return -1;
default:
GetDoc();
} // endswitch ReadDB
if (Find(g))
return -1;
// Missing columns can be null
for (bcp = fbcp; bcp; bcp = bcp->Next) {
bcp->Cbn |= !bcp->Found;
bcp->Found = false;
} // endfor bcp
} // endfor i
return ncol;
} // end of GetColumns
/***********************************************************************/
/* Add a new column in the column list. */
/***********************************************************************/
void MGODISC::AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k)
{
// Check whether this column was already found
for (bcp = fbcp; bcp; bcp = bcp->Next)
if (!strcmp(colname, bcp->Name))
break;
if (bcp) {
if (bcp->Type != bcol.Type)
bcp->Type = TYPE_STRING;
if (k && *fmt && (!bcp->Fmt || strlen(bcp->Fmt) < strlen(fmt))) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} // endif *fmt
bcp->Len = MY_MAX(bcp->Len, bcol.Len);
bcp->Scale = MY_MAX(bcp->Scale, bcol.Scale);
bcp->Cbn |= bcol.Cbn;
bcp->Found = true;
} else {
// New column
bcp = (PBCOL)PlugSubAlloc(g, NULL, sizeof(BCOL));
*bcp = bcol;
bcp->Cbn |= (i > 1);
bcp->Name = PlugDup(g, colname);
length[0] = MY_MAX(length[0], strlen(colname));
if (k) {
bcp->Fmt = PlugDup(g, fmt);
length[7] = MY_MAX(length[7], strlen(fmt));
} else
bcp->Fmt = NULL;
if (pbcp) {
bcp->Next = pbcp->Next;
pbcp->Next = bcp;
} else
fbcp = bcp;
ncol++;
} // endif jcp
pbcp = bcp;
} // end of AddColumn
/* -------------------------- Class MGODEF --------------------------- */
MGODEF::MGODEF(void)
{
Driver = NULL;
Uri = NULL;
Colist = NULL;
Filter = NULL;
Level = 0;
Base = 0;
Version = 0;
Pipe = false;
} // end of MGODEF constructor
/***********************************************************************/
/* DefineAM: define specific AM block values. */
/***********************************************************************/
bool MGODEF::DefineAM(PGLOBAL g, LPCSTR, int poff)
{
if (EXTDEF::DefineAM(g, "MGO", poff))
return true;
else if (!Tabschema)
Tabschema = GetStringCatInfo(g, "Dbname", "*");
Driver = GetStringCatInfo(g, "Driver", NULL);
Uri = GetStringCatInfo(g, "Connect", "mongodb://localhost:27017");
Colist = GetStringCatInfo(g, "Colist", NULL);
Filter = GetStringCatInfo(g, "Filter", NULL);
Base = GetIntCatInfo("Base", 0) ? 1 : 0;
Version = GetIntCatInfo("Version", 3);
if (Version == 2)
Wrapname = GetStringCatInfo(g, "Wrapper", "Mongo2Interface");
else
Wrapname = GetStringCatInfo(g, "Wrapper", "Mongo3Interface");
Pipe = GetBoolCatInfo("Pipeline", false);
return false;
} // end of DefineAM
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB MGODEF::GetTable(PGLOBAL g, MODE m)
{
if (Driver && toupper(*Driver) == 'C') {
#if defined(CMGO_SUPPORT)
if (Catfunc == FNC_COL)
return new(g) TDBGOL(this);
else
return new(g) TDBCMG(this);
#else
sprintf(g->Message, "Mongo %s Driver not available", "C");
return NULL;
#endif
} else if (Driver && toupper(*Driver) == 'J') {
#if defined(JDBC_SUPPORT)
if (Catfunc == FNC_COL)
return new(g) TDBJGL(this);
else
return new(g) TDBJMG(this);
#else
sprintf(g->Message, "Mongo %s Driver not available", "Java");
return NULL;
#endif
} else { // Driver not specified
#if defined(CMGO_SUPPORT)
if (Catfunc == FNC_COL)
return new(g) TDBGOL(this);
else
return new(g) TDBCMG(this);
#else
if (Catfunc == FNC_COL)
return new(g) TDBJGL(this);
else
return new(g) TDBJMG(this);
#endif
} // endif Driver
} // end of GetTable

91
storage/connect/mongo.h Normal file
View File

@@ -0,0 +1,91 @@
/**************** mongo H Declares Source Code File (.H) ***************/
/* Name: mongo.h Version 1.0 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the common MongoDB classes declares. */
/***********************************************************************/
#ifndef __MONGO_H
#define __MONGO_H
#include "osutil.h"
#include "block.h"
#include "colblk.h"
typedef class MGODEF *PMGODEF;
typedef struct _bncol {
struct _bncol *Next;
char *Name;
char *Fmt;
int Type;
int Len;
int Scale;
bool Cbn;
bool Found;
} BCOL, *PBCOL;
/***********************************************************************/
/* Class used to get the columns of a mongo collection. */
/***********************************************************************/
class MGODISC : public BLOCK {
public:
// Constructor
MGODISC(PGLOBAL g, int *lg);
// Methods
virtual bool Init(PGLOBAL g) { return false; }
virtual void GetDoc(void) {}
virtual bool Find(PGLOBAL g) = 0;
// Functions
int GetColumns(PGLOBAL g, PCSZ db, PCSZ uri, PTOS topt);
void AddColumn(PGLOBAL g, PCSZ colname, PCSZ fmt, int k);
// Members
BCOL bcol;
PBCOL bcp, fbcp, pbcp;
PMGODEF tdp;
PTDB tmgp;
PCSZ drv;
int *length;
int i, ncol, lvl;
bool all;
}; // end of MGODISC
/***********************************************************************/
/* MongoDB table. */
/***********************************************************************/
class DllExport MGODEF : public EXTDEF { /* Table description */
friend class TDBCMG;
friend class TDBJMG;
friend class TDBGOL;
friend class TDBJGL;
friend class CMGFAM;
friend class MGODISC;
friend PQRYRES MGOColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
public:
// Constructor
MGODEF(void);
// Implementation
virtual const char *GetType(void) { return "MONGO"; }
// Methods
virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
protected:
// Members
PCSZ Driver; /* MongoDB Driver (C or JAVA) */
PCSZ Uri; /* MongoDB connection URI */
PSZ Wrapname; /* Java wrapper name */
PCSZ Colist; /* Options list */
PCSZ Filter; /* Filtering query */
int Level; /* Used for catalog table */
int Base; /* The array index base */
int Version; /* The Java driver version */
bool Pipe; /* True is Colist is a pipeline */
}; // end of MGODEF
#endif // __MONGO_H

View File

@@ -1,7 +1,7 @@
/************ MONGO FAM C++ Program Source Code File (.CPP) ************/
/* PROGRAM NAME: mongofam.cpp */
/* ------------- */
/* Version 1.1 */
/* Version 1.3 */
/* */
/* COPYRIGHT: */
/* ---------- */
@@ -17,26 +17,6 @@
/* Include relevant sections of the System header files. */
/***********************************************************************/
#include "my_global.h"
#if defined(__WIN__)
//#include <io.h>
//#include <fcntl.h>
//#include <errno.h>
#if defined(__BORLANDC__)
#define __MFC_COMPAT__ // To define min/max as macro
#endif // __BORLANDC__
//#include <windows.h>
#else // !__WIN__
#if defined(UNIX) || defined(UNIV_LINUX)
//#include <errno.h>
#include <unistd.h>
//#if !defined(sun) // Sun has the ftruncate fnc.
//#define USETEMP // Force copy mode for DELETE
//#endif // !sun
#else // !UNIX
//#include <io.h>
#endif // !UNIX
//#include <fcntl.h>
#endif // !__WIN__
/***********************************************************************/
/* Include application header files: */
@@ -54,20 +34,8 @@
#if defined(UNIX) || defined(UNIV_LINUX)
#include "osutil.h"
//#define _fileno fileno
//#define _O_RDONLY O_RDONLY
#endif
// Required to initialize libmongoc's internals
void mongo_init(bool init)
{
if (init)
mongoc_init();
else
mongoc_cleanup();
} // end of mongo_init
/* --------------------------- Class MGOFAM -------------------------- */
/***********************************************************************/
@@ -75,88 +43,39 @@ void mongo_init(bool init)
/***********************************************************************/
MGOFAM::MGOFAM(PJDEF tdp) : DOSFAM((PDOSDEF)NULL)
{
Client = NULL;
Database = NULL;
Collection = NULL;
Cursor = NULL;
Query = NULL;
Opts = NULL;
Cmgp = NULL;
Pcg.Tdbp = NULL;
if (tdp) {
Pcg.Uristr = tdp->Uri;
Pcg.Db_name = tdp->Schema;
Pcg.Coll_name = tdp->Collname;
Pcg.Options = tdp->Options;
Pcg.Filter = tdp->Filter;
Pcg.Pipe = tdp->Pipe && tdp->Options != NULL;
} else {
Pcg.Uristr = NULL;
Pcg.Db_name = NULL;
Pcg.Coll_name = NULL;
Pcg.Options = NULL;
Pcg.Filter = NULL;
Pcg.Pipe = false;
} // endif tdp
To_Fbt = NULL;
Mode = MODE_ANY;
Uristr = tdp->Uri;
Db_name = tdp->Schema;
Coll_name = tdp->Collname;
Options = tdp->Options;
Filter = tdp->Filter;
Done = false;
Pipe = tdp->Pipe;
Lrecl = tdp->Lrecl + tdp->Ending;
} // end of MGOFAM standard constructor
MGOFAM::MGOFAM(PMGOFAM tdfp) : DOSFAM(tdfp)
{
Client = tdfp->Client;
Database = NULL;
Collection = tdfp->Collection;
Cursor = tdfp->Cursor;
Query = tdfp->Query;
Opts = tdfp->Opts;
Pcg = tdfp->Pcg;
To_Fbt = tdfp->To_Fbt;
Mode = tdfp->Mode;
Uristr = tdfp->Uristr;
Db_name = tdfp->Db_name;
Coll_name = tdfp->Coll_name;
Options = tdfp->Options;
Filter = NULL;
Done = tdfp->Done;
Pipe = tdfp->Pipe;
} // end of MGOFAM copy constructor
#if 0
void *MGOFAM::mgo_alloc(size_t n)
{
char *mst = (char*)PlgDBSubAlloc(G, NULL, n + sizeof(size_t));
if (mst) {
*(size_t*)mst = n;
return mst + sizeof(size_t);
} // endif mst
return NULL;
} // end of mgo_alloc
void *MGOFAM::mgo_calloc(size_t n, size_t sz)
{
void *m = mgo_alloc(n * sz);
if (m)
memset(m, 0, n * sz);
return m;
} // end of mgo_calloc
void *MGOFAM::mgo_realloc(void *m, size_t n)
{
if (!m)
return n ? mgo_alloc(n) : NULL;
size_t *osz = (size_t*)((char*)m - sizeof(size_t));
if (n > *osz) {
void *nwm = mgo_alloc(n);
if (nwm)
memcpy(nwm, m, *osz);
return nwm;
} else {
*osz = n;
return m;
} // endif n
} // end of mgo_realloc
#endif // 0
/***********************************************************************/
/* Reset: reset position values at the beginning of file. */
/***********************************************************************/
@@ -175,47 +94,16 @@ int MGOFAM::GetFileLength(PGLOBAL g)
} // end of GetFileLength
/***********************************************************************/
/* Cardinality: returns table cardinality in number of rows. */
/* Cardinality: returns the number of documents in the collection. */
/* This function can be called with a null argument to test the */
/* availability of Cardinality implementation (1 yes, 0 no). */
/***********************************************************************/
int MGOFAM::Cardinality(PGLOBAL g)
{
if (g) {
if (!Init(g)) {
bson_t *query;
const char *jf = NULL;
if (Pipe)
return 10;
else if (Filter)
jf = Filter;
if (jf) {
query = bson_new_from_json((const uint8_t *)jf, -1, &Error);
if (!query) {
htrc("Wrong filter: %s", Error.message);
return 10;
} // endif Query
} else
query = bson_new();
int64_t card = (int)mongoc_collection_count(Collection,
MONGOC_QUERY_NONE, query, 0, 0, NULL, &Error);
if (card < 0)
sprintf(g->Message, "Collection count: %s", Error.message);
bson_destroy(query);
return card;
} else
return -1;
} else
if (!g)
return 1;
return (!Init(g)) ? Cmgp->CollSize(g) : 0;
} // end of Cardinality
/***********************************************************************/
@@ -234,268 +122,22 @@ bool MGOFAM::Init(PGLOBAL g)
if (Done)
return false;
Uri = mongoc_uri_new(Uristr);
/*********************************************************************/
/* Open an C connection for this table. */
/*********************************************************************/
if (!Cmgp) {
Pcg.Tdbp = Tdbp;
Cmgp = new(g) CMgoConn(g, &Pcg);
} else if (Cmgp->IsConnected())
Cmgp->Close();
if (!Uri) {
sprintf(g->Message, "Failed to parse URI: \"%s\"", Uristr);
if (Cmgp->Connect(g))
return true;
} // endif Uri
// Create a new client pool instance
Pool = mongoc_client_pool_new(Uri);
mongoc_client_pool_set_error_api(Pool, 2);
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
mongoc_client_pool_set_appname(Pool, "Connect");
// Create a new client instance
Client = mongoc_client_pool_pop(Pool);
//Client = mongoc_client_new(uristr);
if (!Client) {
sprintf(g->Message, "Failed to get Client");
return true;
} // endif Client
//mongoc_client_set_error_api(Client, 2);
// Register the application name so we can track it in the profile logs
// on the server. This can also be done from the URI.
//mongoc_client_set_appname(Client, "Connect");
// Get a handle on the database Db_name and collection Coll_name
// Database = mongoc_client_get_database(Client, Db_name);
// Collection = mongoc_database_get_collection(Database, Coll_name);
Collection = mongoc_client_get_collection(Client, Db_name, Coll_name);
if (!Collection) {
sprintf(g->Message, "Failed to get Collection %s.%s", Db_name, Coll_name);
return true;
} // endif Collection
Done = true;
return false;
} // end of Init
/***********************************************************************/
/* OpenDB: Data Base open routine for MONGO access method. */
/***********************************************************************/
bool MGOFAM::MakeCursor(PGLOBAL g)
{
const char *p;
bool b = false, id = (Mode != MODE_READ), all = false;
uint len;
PSZ jp;
PCOL cp;
PSTRG s = NULL;
if (Options && !stricmp(Options, "all")) {
Options = NULL;
all = true;
} // endif Options
for (cp = Tdbp->GetColumns(); cp; cp = cp->GetNext())
if (!strcmp(cp->GetName(), "_id"))
id = true;
else if (cp->GetFmt() && !strcmp(cp->GetFmt(), "*") && !Options)
all = true;
if (Pipe) {
if (trace)
htrc("Pipeline: %s\n", Options);
p = strrchr(Options, ']');
if (!p) {
strcpy(g->Message, "Missing ] in pipeline");
return true;
} else
*(char*)p = 0;
s = new(g) STRING(g, 1023, (PSZ)Options);
len = s->GetLength();
if (Tdbp->GetFilter()) {
s->Append(",{\"$match\":");
if (!Tdbp->GetFilter()->MakeSelector(g, s, false)) {
s->Append('}');
Tdbp->SetFilter(NULL); // Not needed anymore
} else {
if (((TDBJSN*)Tdbp)->Xcol)
Tdbp->SetFilter(NULL); // Incompatible
htrc("Failed making selector\n");
s->Truncate(len);
} // endif Selector
} // endif To_Filter
if (!all) {
// Project list
len = s->GetLength();
if (Tdbp->GetColumns()) {
s->Append(",{\"$project\":{\"");
if (!id)
s->Append("_id\":0,\"");
for (PCOL cp = Tdbp->GetColumns(); cp; cp = cp->GetNext()) {
if (b)
s->Append(",\"");
else
b = true;
if ((jp = ((PJCOL)cp)->GetJpath(g, true)))
s->Append(jp);
else {
s->Truncate(len);
goto nop;
} // endif Jpath
s->Append("\":1");
} // endfor cp
} else
s->Append(",{\"$project\":{\"_id\":1}}");
s->Append("}}");
} // endif all
nop:
s->Append("]}");
s->Resize(s->GetLength() + 1);
p = s->GetStr();
if (trace)
htrc("New Pipeline: %s\n", p);
Query = bson_new_from_json((const uint8_t *)p, -1, &Error);
if (!Query) {
sprintf(g->Message, "Wrong pipeline: %s", Error.message);
return true;
} // endif Query
Cursor = mongoc_collection_aggregate(Collection, MONGOC_QUERY_NONE,
Query, NULL, NULL);
if (mongoc_cursor_error(Cursor, &Error)) {
sprintf(g->Message, "Mongo aggregate Failure: %s", Error.message);
return true;
} // endif cursor
} else {
if (Filter || Tdbp->GetFilter()) {
if (trace) {
if (Filter)
htrc("Filter: %s\n", Filter);
if (Tdbp->GetFilter()) {
char buf[512];
Tdbp->GetFilter()->Prints(g, buf, 511);
htrc("To_Filter: %s\n", buf);
} // endif To_Filter
} // endif trace
s = new(g) STRING(g, 1023, (PSZ)Filter);
len = s->GetLength();
if (Tdbp->GetFilter()) {
if (Filter)
s->Append(',');
if (Tdbp->GetFilter()->MakeSelector(g, s, false)) {
if (((TDBJSN*)Tdbp)->Xcol)
Tdbp->SetFilter(NULL); // Incompatible
htrc("Cannot make selector\n");
s->Truncate(len);
} else
Tdbp->SetFilter(NULL); // Not needed anymore
} // endif To_Filter
if (trace)
htrc("selector: %s\n", s->GetStr());
s->Resize(s->GetLength() + 1);
if (s->GetLength()) {
Query = bson_new_from_json((const uint8_t *)s->GetStr(), -1, &Error);
if (!Query) {
sprintf(g->Message, "Wrong filter: %s", Error.message);
return true;
} // endif Query
} else
Query = bson_new();
} else
Query = bson_new();
if (!all) {
if (Options && *Options) {
if (trace)
htrc("options=%s\n", Options);
p = Options;
} else if (Tdbp->GetColumns()) {
// Projection list
if (s)
s->Set("{\"projection\":{\"");
else
s = new(g) STRING(g, 511, "{\"projection\":{\"");
if (!id)
s->Append("_id\":0,\"");
for (PCOL cp = Tdbp->GetColumns(); cp; cp = cp->GetNext()) {
if (b)
s->Append(",\"");
else
b = true;
if ((jp = ((PJCOL)cp)->GetJpath(g, true)))
s->Append(jp);
else {
s->Reset();
s->Resize(0);
goto nope;
} // endif Jpath
s->Append("\":1");
} // endfor cp
s->Append("}}");
s->Resize(s->GetLength() + 1);
p = s->GetStr();
} else {
// count(*) ?
p = "{\"projection\":{\"_id\":1}}";
} // endif Options
Opts = bson_new_from_json((const uint8_t *)p, -1, &Error);
if (!Opts) {
sprintf(g->Message, "Wrong options: %s", Error.message);
return true;
} // endif Opts
} // endif all
nope:
Cursor = mongoc_collection_find_with_opts(Collection, Query, Opts, NULL);
} // endif Pipe
return false;
} // end of MakeCursor
/***********************************************************************/
/* OpenTableFile: Open a MongoDB table. */
/***********************************************************************/
@@ -503,7 +145,7 @@ bool MGOFAM::OpenTableFile(PGLOBAL g)
{
Mode = Tdbp->GetMode();
if (Pipe && Mode != MODE_READ) {
if (Pcg.Pipe && Mode != MODE_READ) {
strcpy(g->Message, "Pipeline tables are read only");
return true;
} // endif Pipe
@@ -511,20 +153,11 @@ bool MGOFAM::OpenTableFile(PGLOBAL g)
if (Init(g))
return true;
if (Mode == MODE_DELETE && !Tdbp->GetNext()) {
// Store the number of deleted lines
DelRows = Cardinality(g);
if (Mode == MODE_DELETE && !Tdbp->GetNext())
// Delete all documents
if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE,
Query, NULL, &Error)) {
sprintf(g->Message, "Remove all: %s", Error.message);
return true;
} // endif remove
} else if (Mode != MODE_INSERT)
if (MakeCursor(g))
return true;
return Cmgp->DocDelete(g);
else if (Mode == MODE_INSERT)
Cmgp->MakeColumnGroups(g);
return false;
} // end of OpenTableFile
@@ -589,91 +222,18 @@ int MGOFAM::SkipRecord(PGLOBAL g, bool header)
return RC_OK; // Dummy
} // end of SkipRecord
/***********************************************************************/
/* Use to trace restaurants document contains. */
/***********************************************************************/
void MGOFAM::ShowDocument(bson_iter_t *iter, const bson_t *doc, const char *k)
{
if (!doc || bson_iter_init(iter, doc)) {
const char *key;
while (bson_iter_next(iter)) {
key = bson_iter_key(iter);
htrc("Found element key: \"%s\"\n", key);
if (BSON_ITER_HOLDS_UTF8(iter))
htrc("%s.%s=\"%s\"\n", k, key, bson_iter_utf8(iter, NULL));
else if (BSON_ITER_HOLDS_INT32(iter))
htrc("%s.%s=%d\n", k, key, bson_iter_int32(iter));
else if (BSON_ITER_HOLDS_INT64(iter))
htrc("%s.%s=%lld\n", k, key, bson_iter_int64(iter));
else if (BSON_ITER_HOLDS_DOUBLE(iter))
htrc("%s.%s=%g\n", k, key, bson_iter_double(iter));
else if (BSON_ITER_HOLDS_DATE_TIME(iter))
htrc("%s.%s=date(%lld)\n", k, key, bson_iter_date_time(iter));
else if (BSON_ITER_HOLDS_OID(iter)) {
char str[25];
bson_oid_to_string(bson_iter_oid(iter), str);
htrc("%s.%s=%s\n", k, key, str);
} else if (BSON_ITER_HOLDS_DECIMAL128(iter)) {
char *str = NULL;
bson_decimal128_t dec;
bson_iter_decimal128(iter, &dec);
bson_decimal128_to_string(&dec, str);
htrc("%s.%s=%s\n", k, key, str);
} else if (BSON_ITER_HOLDS_DOCUMENT(iter)) {
bson_iter_t child;
if (bson_iter_recurse(iter, &child))
ShowDocument(&child, NULL, key);
} else if (BSON_ITER_HOLDS_ARRAY(iter)) {
bson_t *arr;
bson_iter_t itar;
const uint8_t *data = NULL;
uint32_t len = 0;
bson_iter_array(iter, &len, &data);
arr = bson_new_from_data(data, len);
ShowDocument(&itar, arr, key);
} // endif's
} // endwhile bson_iter_next
} // endif bson_iter_init
} // end of ShowDocument
/***********************************************************************/
/* ReadBuffer: Get next document from a collection. */
/***********************************************************************/
int MGOFAM::ReadBuffer(PGLOBAL g)
{
int rc = RC_OK;
int rc = Cmgp->ReadNext(g);
if (mongoc_cursor_next(Cursor, &Document)) {
char *str = bson_as_json(Document, NULL);
if (rc != RC_OK)
return rc;
if (trace > 1) {
bson_iter_t iter;
ShowDocument(&iter, Document, "");
} else if (trace == 1)
htrc("%s\n", str);
strncpy(Tdbp->GetLine(), str, Lrecl);
bson_free(str);
} else if (mongoc_cursor_error(Cursor, &Error)) {
sprintf(g->Message, "Mongo Cursor Failure: %s", Error.message);
rc = RC_FX;
} else {
//mongoc_cursor_destroy(Cursor);
rc = RC_EF;
} // endif's Cursor
return rc;
strncpy(Tdbp->GetLine(), Cmgp->GetDocument(g), Lrecl);
return RC_OK;
} // end of ReadBuffer
/***********************************************************************/
@@ -681,84 +241,7 @@ int MGOFAM::ReadBuffer(PGLOBAL g)
/***********************************************************************/
int MGOFAM::WriteBuffer(PGLOBAL g)
{
int rc = RC_OK;
bson_t *doc;
//if (Mode == MODE_INSERT && !Collection) {
// if ((Database = mongoc_client_get_database(Client, db_name)))
// Collection = mongoc_database_create_collection(Database, coll_name,
// NULL, &Error);
// if (!Collection)
// if (Database) {
// sprintf(g->Message, "Create collection: %s", Error.message);
// return RC_FX;
// } else {
// sprintf(g->Message, "Fail to get database %s", db_name);
// return RC_FX;
// } // endif Database
//} // endif Collection
if (!(doc = bson_new_from_json((const uint8_t *)Tdbp->GetLine(),
-1, &Error))) {
sprintf(g->Message, "Wrong document: %s", Error.message);
return RC_FX;
} // endif doc
if (Mode != MODE_INSERT) {
bool b = false;
bson_iter_t iter;
bson_t *selector = bson_new();
bson_iter_init(&iter, Document);
if (bson_iter_find(&iter, "_id")) {
if (BSON_ITER_HOLDS_OID(&iter))
b = BSON_APPEND_OID(selector, "_id", bson_iter_oid(&iter));
else if (BSON_ITER_HOLDS_INT32(&iter))
b = BSON_APPEND_INT32(selector, "_id", bson_iter_int32(&iter));
else if (BSON_ITER_HOLDS_INT64(&iter))
b = BSON_APPEND_INT64(selector, "_id", bson_iter_int64(&iter));
else if (BSON_ITER_HOLDS_DOUBLE(&iter))
b = BSON_APPEND_DOUBLE(selector, "_id", bson_iter_double(&iter));
else if (BSON_ITER_HOLDS_UTF8(&iter))
b = BSON_APPEND_UTF8(selector, "_id", bson_iter_utf8(&iter, NULL));
} // endif iter
if (!b) {
strcpy(g->Message, "Cannot find _id");
return RC_FX;
} // endif oid
if (Mode == MODE_DELETE) {
if (!mongoc_collection_remove(Collection, MONGOC_REMOVE_NONE,
selector, NULL, &Error)) {
sprintf(g->Message, "Remove: %s", Error.message);
bson_destroy(selector);
return RC_FX;
} // endif remove
} else {
if (!mongoc_collection_update(Collection, MONGOC_UPDATE_NONE,
selector, doc, NULL, &Error)) {
sprintf(g->Message, "Update: %s", Error.message);
bson_destroy(selector);
return RC_FX;
} // endif remove
} // endif Mode
bson_destroy(selector);
} else if (!mongoc_collection_insert(Collection, MONGOC_INSERT_NONE,
doc, NULL, &Error)) {
sprintf(g->Message, "Inserting: %s", Error.message);
rc = RC_FX;
} // endif insert
bson_destroy(doc);
return rc;
return Cmgp->Write(g);
} // end of WriteBuffer
/***********************************************************************/
@@ -774,18 +257,7 @@ int MGOFAM::DeleteRecords(PGLOBAL g, int irc)
/***********************************************************************/
void MGOFAM::CloseTableFile(PGLOBAL g, bool)
{
if (Query) bson_destroy(Query);
if (Opts) bson_destroy(Opts);
if (Cursor) mongoc_cursor_destroy(Cursor);
if (Collection) mongoc_collection_destroy(Collection);
// mongoc_database_destroy(Database);
// mongoc_client_destroy(Client);
if (Client) mongoc_client_pool_push(Pool, Client);
if (Pool) mongoc_client_pool_destroy(Pool);
if (Uri) mongoc_uri_destroy(Uri);
//bson_mem_restore_vtable();
//mongoc_cleanup();
//G = NULL;
Cmgp->Close();
Done = false;
} // end of CloseTableFile
@@ -794,9 +266,6 @@ void MGOFAM::CloseTableFile(PGLOBAL g, bool)
/***********************************************************************/
void MGOFAM::Rewind(void)
{
mongoc_cursor_t *cursor = mongoc_cursor_clone(Cursor);
mongoc_cursor_destroy(Cursor);
Cursor = cursor;
Cmgp->Rewind();
} // end of Rewind

View File

@@ -1,21 +1,11 @@
/************** MongoFam H Declares Source Code File (.H) **************/
/* Name: mongofam.h Version 1.3 */
/* Name: mongofam.h Version 1.4 */
/* */
/* (C) Copyright to the author Olivier BERTRAND 2017 */
/* */
/* This file contains the MongoDB access method classes declares. */
/***********************************************************************/
#pragma once
/***********************************************************************/
/* Include MongoDB library header files. */
/***********************************************************************/
#include <bson.h>
#include <bcon.h>
#include <mongoc.h>
#include "block.h"
//#include "array.h"
#include "cmgoconn.h"
typedef class TXTFAM *PTXF;
typedef class MGOFAM *PMGOFAM;
@@ -37,6 +27,7 @@ public:
virtual bool GetUseTemp(void) { return false; }
virtual int GetPos(void);
virtual int GetNextPos(void);
void SetTdbp(PTDBDOS tdbp) { Tdbp = tdbp; }
virtual PTXF Duplicate(PGLOBAL g) { return (PTXF)new(g) MGOFAM(this); }
void SetLrecl(int lrecl) { Lrecl = lrecl; }
@@ -63,35 +54,12 @@ protected:
virtual int RenameTempFile(PGLOBAL g) { return RC_OK; }
virtual int InitDelete(PGLOBAL g, int fpos, int spos);
bool Init(PGLOBAL g);
bool MakeCursor(PGLOBAL g);
void ShowDocument(bson_iter_t *i, const bson_t *b, const char *k);
//static void *mgo_alloc(size_t n);
//static void *mgo_calloc(size_t n, size_t sz);
//static void *mgo_realloc(void *m, size_t n);
//static void mgo_free(void *) {}
// Members
//static PGLOBAL G;
mongoc_uri_t *Uri;
mongoc_client_pool_t *Pool; // Thread safe client pool
mongoc_client_t *Client; // The MongoDB client
mongoc_database_t *Database; // The MongoDB database
mongoc_collection_t *Collection; // The MongoDB collection
mongoc_cursor_t *Cursor;
const bson_t *Document;
//bson_mem_vtable_t Vtable;
bson_t *Query; // MongoDB cursor filter
bson_t *Opts; // MongoDB cursor options
bson_error_t Error;
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
const char *Uristr;
const char *Db_name;
const char *Coll_name;
const char *Options;
const char *Filter;
bool Done; // Init done
bool Pipe;
CMgoConn *Cmgp; // Points to a C Mongo connection class
CMGOPARM Pcg; // Parms passed to Cmgp
PFBLOCK To_Fbt; // Pointer to temp file block
MODE Mode;
bool Done; // Init done
}; // end of class MGOFAM

View File

@@ -1,3 +1,4 @@
/* Copyright (C) MariaDB Corporation Ab */
#define MSG_ACCESS_VIOLATN 200
#define MSG_ADD_BAD_TYPE 201
#define MSG_ALLOC_ERROR 202

View File

@@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2017
/* Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -86,7 +86,7 @@
#if defined(JDBC_SUPPORT)
#define NJDBC
#include "tabjdbc.h"
#endif // ODBC_SUPPORT
#endif // JDBC_SUPPORT
#if defined(PIVOT_SUPPORT)
#include "tabpivot.h"
#endif // PIVOT_SUPPORT
@@ -97,7 +97,7 @@
#include "tabxml.h"
#endif // XML_SUPPORT
#if defined(MONGO_SUPPORT)
#include "tabmgo.h"
#include "mongo.h"
#endif // MONGO_SUPPORT
#if defined(ZIP_SUPPORT)
#include "tabzip.h"
@@ -133,21 +133,21 @@ TABTYPE GetTypeID(const char *type)
: (!stricmp(type, "CSV")) ? TAB_CSV
: (!stricmp(type, "FMT")) ? TAB_FMT
: (!stricmp(type, "DBF")) ? TAB_DBF
#ifdef XML_SUPPORT
#if defined(XML_SUPPORT)
: (!stricmp(type, "XML")) ? TAB_XML
#endif
: (!stricmp(type, "INI")) ? TAB_INI
: (!stricmp(type, "VEC")) ? TAB_VEC
#ifdef ODBC_SUPPORT
#if defined(ODBC_SUPPORT)
: (!stricmp(type, "ODBC")) ? TAB_ODBC
#endif
#ifdef JDBC_SUPPORT
#if defined(JDBC_SUPPORT)
: (!stricmp(type, "JDBC")) ? TAB_JDBC
#endif
: (!stricmp(type, "MYSQL")) ? TAB_MYSQL
: (!stricmp(type, "MYPRX")) ? TAB_MYSQL
: (!stricmp(type, "DIR")) ? TAB_DIR
#ifdef __WIN__
#if defined(__WIN__)
: (!stricmp(type, "MAC")) ? TAB_MAC
: (!stricmp(type, "WMI")) ? TAB_WMI
#endif
@@ -156,15 +156,15 @@ TABTYPE GetTypeID(const char *type)
: (!stricmp(type, "OCCUR")) ? TAB_OCCUR
: (!stricmp(type, "CATLG")) ? TAB_PRX // Legacy
: (!stricmp(type, "PROXY")) ? TAB_PRX
#ifdef PIVOT_SUPPORT
#if defined(PIVOT_SUPPORT)
: (!stricmp(type, "PIVOT")) ? TAB_PIVOT
#endif
: (!stricmp(type, "VIR")) ? TAB_VIR
: (!stricmp(type, "JSON")) ? TAB_JSON
#ifdef ZIP_SUPPORT
#if defined(ZIP_SUPPORT)
: (!stricmp(type, "ZIP")) ? TAB_ZIP
#endif
#ifdef MONGO_SUPPORT
#if defined(MONGO_SUPPORT)
: (!stricmp(type, "MONGO")) ? TAB_MONGO
#endif
: (!stricmp(type, "OEM")) ? TAB_OEM : TAB_NIY;

View File

@@ -1,4 +1,4 @@
/* Copyright (C) Olivier Bertrand 2004 - 2015
/* Copyright (C) MariaDB Corporation Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
/**************** MYCAT H Declares Source Code File (.H) ***************/
/* Name: MYCAT.H Version 2.3 */
/* */
/* Author: Olivier Bertrand */
/* This file contains the CONNECT plugin MYCAT class definitions. */
/***********************************************************************/
#ifndef __MYCAT__H

View File

@@ -13,5 +13,9 @@ jdbc : Variable settings depend on machine configuration
jdbc_new : Variable settings depend on machine configuration
jdbc_oracle : Variable settings depend on machine configuration
jdbc_postgresql : Variable settings depend on machine configuration
json_mgo : Need MongoDB running and its C Driver installed
mongo : Need MongoDB running and its C Driver installed
json_mongo_c : Need MongoDB running and its C Driver installed
json_java_2 : Need MongoDB running and its Java Driver installed
json_java_3 : Need MongoDB running and its Java Driver installed
mongo_c : Need MongoDB running and its C Driver installed
mongo_java_2 : Need MongoDB running and its Java Driver installed
mongo_java_3 : Need MongoDB running and its Java Driver installed

View File

@@ -1,5 +1,3 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Testing changing table type (not in-place)
#
@@ -16,7 +14,7 @@ c d
# This is because the XML top node name defaults to the table name.
# Sure enough the temporary table name begins with '#' and is rejected by XML.
# Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='rownode=row';
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='xmlsup=domdoc,rownode=row';
SELECT * FROM t1;
c d
1 One
@@ -27,7 +25,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `HEADER`=1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='rownode=row'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `HEADER`=1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='xmlsup=domdoc,rownode=row'
# Let us see the XML file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.xml';
Warnings:
@@ -67,7 +65,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL `FIELD_FORMAT`='@'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='rownode=row' `HEADER`=0
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='xmlsup=domdoc,rownode=row' `HEADER`=0
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>

View File

@@ -0,0 +1,86 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Testing changing table type (not in-place)
#
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV HEADER=1 QUOTED=1;
Warnings:
Warning 1105 No file name. Table will use t1.csv
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
# This would fail if the top node name is not specified.
# This is because the XML top node name defaults to the table name.
# Sure enough the temporary table name begins with '#' and is rejected by XML.
# Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='xmlsup=libxml2,rownode=row';
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `HEADER`=1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='xmlsup=libxml2,rownode=row'
# Let us see the XML file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.xml';
Warnings:
Warning 1105 No table_type. Will be set to DOS
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by the MariaDB CONNECT Storage Engine-->
<t1>
<row>
<TH>c</TH>
<TH>d</TH>
</row>
<row>
<c>1</c>
<d>One</d>
</row>
<row>
<c>2</c>
<d>Two</d>
</row>
<row>
<c>3</c>
<d>Three</d>
</row>
</t1>
# NOTE: The first (ignored) row is due to the remaining HEADER=1 option.
# Testing field option modification
ALTER TABLE t1 MODIFY d CHAR(10) NOT NULL FIELD_FORMAT='@', HEADER=0;
SELECT * FROM t1;
c d
1 One
2 Two
3 Three
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c` int(11) NOT NULL,
`d` char(10) NOT NULL `FIELD_FORMAT`='@'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `QUOTED`=1 `TABLE_TYPE`=XML `TABNAME`=t1 `OPTION_LIST`='xmlsup=libxml2,rownode=row' `HEADER`=0
SELECT * FROM t2;
line
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by the MariaDB CONNECT Storage Engine-->
<t1>
<row d="One">
<c>1</c>
</row>
<row d="Two">
<c>2</c>
</row>
<row d="Three">
<c>3</c>
</row>
</t1>
DROP TABLE t1, t2;

View File

@@ -57,7 +57,7 @@ t1 CREATE TABLE `t1` (
`name` char(10) NOT NULL,
`birth` date NOT NULL,
`id` char(5) NOT NULL `FIELD_FORMAT`='S',
`salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F',
`salary` double(9,2) NOT NULL DEFAULT 0.00 `FIELD_FORMAT`='F',
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `OPTION_LIST`='Endian=Little' `READONLY`=NO
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);
@@ -76,7 +76,7 @@ t1 CREATE TABLE `t1` (
`name` char(10) NOT NULL,
`birth` date NOT NULL,
`id` char(5) NOT NULL `FIELD_FORMAT`='S',
`salary` double(9,2) NOT NULL DEFAULT '0.00' `FIELD_FORMAT`='F',
`salary` double(9,2) NOT NULL DEFAULT 0.00 `FIELD_FORMAT`='F',
`dept` int(4) NOT NULL `FIELD_FORMAT`='S'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=BIN `FILE_NAME`='Testbal.dat' `OPTION_LIST`='Endian=Little' `READONLY`=YES
INSERT INTO t1 VALUES (7777,'BILL','1973-06-30',4444,5555.555,777);

View File

@@ -26,7 +26,7 @@ fname ftype size
boys .txt 282
boyswin .txt 288
INSERT INTO t1 VALUES ('','','','');
ERROR HY000: Got error 174 'COLBLK SetBuffer: undefined Access Method' from CONNECT
ERROR 22007: Incorrect double value: '' for column 'size' at row 1
DROP TABLE t1;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*.txt';
ERROR HY000: Cannot get column info for table type DIR

View File

@@ -4,6 +4,8 @@ set sql_mode="";
#
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -14,6 +16,7 @@ ftype CHAR(4) NOT NULL,
size DOUBLE(12,0) NOT NULL flag=5
) ENGINE=CONNECT TABLE_TYPE=DIR FILE_NAME='*.*';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -26,6 +29,7 @@ size DOUBLE(12,0) NOT NULL flag=5
SELECT fname, ftype, size FROM t1 WHERE size>0;
fname ftype size
t1 .frm 1081
connection user;
SELECT user();
user()
user@localhost
@@ -44,10 +48,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -59,6 +65,8 @@ UPDATE v1 SET path=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
disconnect user;
connection default;
SELECT user();
user()
root@localhost
@@ -74,6 +82,8 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -102,11 +112,13 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
@@ -129,10 +141,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -144,6 +158,7 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -153,12 +168,15 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=BIN;
Warnings:
Warning 1105 No file name. Table will use t1.bin
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -169,6 +187,8 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -197,11 +217,13 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
@@ -224,10 +246,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -239,6 +263,7 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -248,12 +273,15 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV;
Warnings:
Warning 1105 No file name. Table will use t1.csv
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -264,6 +292,8 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -292,11 +322,13 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
@@ -319,10 +351,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -334,6 +368,7 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -343,12 +378,15 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=DBF;
Warnings:
Warning 1105 No file name. Table will use t1.dbf
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -359,6 +397,8 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -387,11 +427,13 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
@@ -414,10 +456,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -429,6 +473,7 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -438,12 +483,15 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=FIX;
Warnings:
Warning 1105 No file name. Table will use t1.fix
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
@@ -454,6 +502,8 @@ DROP USER user@localhost;
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -482,11 +532,13 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=VEC MAX_ROWS=100 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=VEC MAX_ROWS=100 FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
@@ -509,10 +561,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -524,6 +578,7 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -533,12 +588,15 @@ CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=VEC MAX_ROWS=100;
Warnings:
Warning 1105 No file name. Table will use t1.vec
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc

View File

@@ -5,6 +5,7 @@ CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
# Testing SQLCOM_SELECT
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -21,6 +22,7 @@ a
10
SELECT * FROM v1_baddefiner;
ERROR 28000: Access denied for user 'root'@'localhost' (using password: NO)
connect user,localhost,user,,;
SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT * FROM v1_invoker;
@@ -28,9 +30,11 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT * FROM v1_definer;
a
10
connection default;
DROP VIEW v1_invoker, v1_definer, v1_baddefiner;
DROP TABLE t1;
# Testing SQLCOM_UPDATE
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -38,14 +42,17 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
UPDATE t1 SET a=11;
UPDATE v1_invoker SET a=12;
UPDATE v1_definer SET a=13;
connection user;
UPDATE t1 SET a=21;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v1_invoker SET a=22;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v1_definer SET a=23;
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_INSERT
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -53,14 +60,17 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
INSERT INTO t1 VALUES (11);
INSERT INTO v1_invoker VALUES (12);
INSERT INTO v1_definer VALUES (13);
connection user;
INSERT INTO t1 VALUES (21);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_invoker VALUES (22);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_definer VALUES (23);
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_REPLACE
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -71,15 +81,18 @@ REPLACE INTO v1_invoker VALUES (12);
ERROR 42000: CONNECT Unsupported command
REPLACE INTO v1_definer VALUES (13);
ERROR 42000: CONNECT Unsupported command
connection user;
REPLACE INTO t1 VALUES (21);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
REPLACE INTO v1_invoker VALUES (22);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
REPLACE INTO v1_definer VALUES (23);
ERROR 42000: CONNECT Unsupported command
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_DELETE
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10),(11),(12),(13),(21),(22),(23);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -87,14 +100,17 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
DELETE FROM t1 WHERE a=11;
DELETE FROM v1_invoker WHERE a=12;
DELETE FROM v1_definer WHERE a=13;
connection user;
DELETE FROM t1 WHERE a=21;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1_invoker WHERE a=22;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1_definer WHERE a=23;
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_LOAD
connection default;
CREATE TABLE t1 (a VARCHAR(128)) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -102,29 +118,38 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE t1;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_invoker;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_definer;
connection user;
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_invoker;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
LOAD DATA LOCAL INFILE 'MTR_SUITE_DIR/std_data/boys.txt' INTO TABLE v1_definer;
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_TRUNCATE
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
TRUNCATE TABLE t1;
INSERT INTO t1 VALUES (11);
connection user;
TRUNCATE TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_DROP_TABLE
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
connection user;
DROP TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_DROP_VIEW
# DROP VIEW does not need FILE_ACL.
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10),(11),(12),(13),(21),(22),(23);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -132,13 +157,18 @@ CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
DROP VIEW v1_invoker, v1_definer;
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
CREATE SQL SECURITY DEFINER VIEW v1_definer AS SELECT * FROM t1;
connection user;
DROP VIEW v1_invoker;
DROP VIEW v1_definer;
connection default;
DROP TABLE t1;
# Testing SQLCOM_CREATE_TABLE
connection user;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
# Testing SQLCOM_LOCK_TABLES
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -155,6 +185,7 @@ LOCK TABLE v1_definer READ;
UNLOCK TABLES;
LOCK TABLE v1_definer WRITE;
UNLOCK TABLES;
connection user;
LOCK TABLE t1 READ;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
LOCK TABLE t1 WRITE;
@@ -167,9 +198,11 @@ LOCK TABLE v1_definer READ;
UNLOCK TABLES;
LOCK TABLE v1_definer WRITE;
UNLOCK TABLES;
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_UPDATE_MULTI
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
CREATE TABLE t2 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t2.fix';
CREATE TABLE t3 (a INT);
@@ -229,6 +262,7 @@ UPDATE v2_definer a1,v1_invoker a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v1_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v2_invoker a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v2_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
connection user;
UPDATE t1 a1,t1 a2 SET a1.a=50 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE t1 a1,t2 a2 SET a1.a=50 WHERE a1.a=a2.a;
@@ -318,9 +352,11 @@ UPDATE v2_definer a1,v1_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
UPDATE v2_definer a1,v2_invoker a2 SET a1.a=50 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v2_definer a1,v2_definer a2 SET a1.a=50 WHERE a1.a=a2.a;
connection default;
DROP VIEW v1_invoker, v1_definer, v2_invoker, v2_definer;
DROP TABLE t1, t2, t3;
# Testing SQLCOM_DELETE_MULTI
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
CREATE TABLE t2 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t2.fix';
CREATE TABLE t3 (a INT);
@@ -380,6 +416,7 @@ DELETE a1 FROM v2_definer a1,v1_invoker a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v1_definer a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v2_invoker a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v2_definer a2 WHERE a1.a=a2.a;
connection user;
DELETE a1 FROM t1 a1,t1 a2 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE a1 FROM t1 a1,t2 a2 WHERE a1.a=a2.a;
@@ -469,9 +506,11 @@ DELETE a1 FROM v2_definer a1,v1_definer a2 WHERE a1.a=a2.a;
DELETE a1 FROM v2_definer a1,v2_invoker a2 WHERE a1.a=a2.a;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE a1 FROM v2_definer a1,v2_definer a2 WHERE a1.a=a2.a;
connection default;
DROP VIEW v1_invoker, v1_definer, v2_invoker, v2_definer;
DROP TABLE t1, t2, t3;
# Testing SQLCOM_CREATE_VIEW
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -480,15 +519,18 @@ CREATE VIEW v2 AS SELECT * FROM v1_invoker;
DROP VIEW v2;
CREATE VIEW v2 AS SELECT * FROM v1_definer;
DROP VIEW v2;
connection user;
CREATE VIEW v2 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v2 AS SELECT * FROM v1_invoker;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v2 AS SELECT * FROM v1_definer;
DROP VIEW v2;
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_INSERT_SELECT
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -502,6 +544,7 @@ INSERT INTO v1_invoker SELECT * FROM v1_definer WHERE a=20;
INSERT INTO v1_definer SELECT * FROM t1 WHERE a=20;
INSERT INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
INSERT INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
connection user;
INSERT INTO t1 SELECT * FROM t1 WHERE a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO t1 SELECT * FROM v1_invoker WHERE a=20;
@@ -519,9 +562,11 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_REPLACE_SELECT
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
CREATE SQL SECURITY INVOKER VIEW v1_invoker AS SELECT * FROM t1;
@@ -544,6 +589,7 @@ REPLACE INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
ERROR 42000: CONNECT Unsupported command
REPLACE INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
ERROR 42000: CONNECT Unsupported command
connection user;
REPLACE INTO t1 SELECT * FROM t1 WHERE a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
REPLACE INTO t1 SELECT * FROM v1_invoker WHERE a=20;
@@ -562,9 +608,11 @@ REPLACE INTO v1_definer SELECT * FROM v1_invoker WHERE a=20;
ERROR 42000: CONNECT Unsupported command
REPLACE INTO v1_definer SELECT * FROM v1_definer WHERE a=20;
ERROR 42000: CONNECT Unsupported command
connection default;
DROP VIEW v1_invoker, v1_definer;
DROP TABLE t1;
# Testing SQLCOM_RENAME_TABLE
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
RENAME TABLE t1 TO t2;
@@ -574,10 +622,13 @@ t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='t1.fix'
RENAME TABLE t2 TO t1;
connection user;
RENAME TABLE t1 TO t2;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (for ALTER..RENAME)
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
ALTER TABLE t1 RENAME TO t2;
@@ -587,20 +638,26 @@ t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=fix `FILE_NAME`='t1.fix'
ALTER TABLE t2 RENAME TO t1;
connection user;
ALTER TABLE t1 RENAME TO t2;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (changing ENGINE to non-CONNECT)
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
ALTER TABLE t1 ENGINE=MyISAM;
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
connection user;
ALTER TABLE t1 ENGINE=MyISAM;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (changing ENGINE to CONNECT)
connection default;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
@@ -610,63 +667,83 @@ ALTER TABLE t1 ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (10);
connection user;
ALTER TABLE t1 ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_OPTIMIZE
connection default;
CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
connection user;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize Error Access denied for user 'user'@'localhost' (using password: NO)
test.t1 optimize Error Got error 122 'This operation requires the FILE privilege' from CONNECT
test.t1 optimize error Corrupt
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (adding columns)
connection default;
CREATE TABLE t1 (a INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10);
ALTER TABLE t1 ADD b INT;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
connection user;
ALTER TABLE t1 ADD c INT;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (removing columns)
connection default;
CREATE TABLE t1 (a INT,b INT,c INT) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10,10);
ALTER TABLE t1 DROP b;
Warnings:
Warning 1105 This is an outward table, table data were not modified.
connection user;
ALTER TABLE t1 DROP c;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (adding keys)
connection default;
CREATE TABLE t1 (a INT NOT NULL,b INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10);
ALTER TABLE t1 ADD KEY(a);
connection user;
ALTER TABLE t1 ADD KEY(b);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_ALTER_TABLE (removing keys)
connection default;
CREATE TABLE t1 (a INT NOT NULL,b INT NOT NULL, KEY a(a), KEY b(b)) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10);
ALTER TABLE t1 DROP KEY a;
connection user;
ALTER TABLE t1 DROP KEY b;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing SQLCOM_CREATE_INDEX and SQLCOM_DROP_INDEX
connection default;
CREATE TABLE t1 (a INT NOT NULL,b INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=fix FILE_NAME='t1.fix';
INSERT INTO t1 VALUES (10,10);
CREATE INDEX a ON t1 (a);
DROP INDEX a ON t1;
CREATE INDEX a ON t1 (a);
connection user;
CREATE INDEX b ON t1 (b);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DROP INDEX a ON t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
# Testing stored procedures
CREATE PROCEDURE p_definer() SQL SECURITY DEFINER
@@ -681,9 +758,11 @@ CALL p_invoker();
DROP TABLE t1;
CALL p_baddefiner();
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection user;
CALL p_invoker();
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CALL p_definer();
connection default;
DROP TABLE t1;
DROP PROCEDURE p_definer;
DROP PROCEDURE p_invoker;

View File

@@ -1,6 +1,4 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
create table t1 (i int) engine=Connect table_type=XML;
create table t1 (i int) engine=Connect table_type=XML option_list='xmlsup=domdoc';
Warnings:
Warning 1105 No file name. Table will use t1.xml
select * from information_schema.tables where create_options like '%table_type=XML%';

View File

@@ -0,0 +1,12 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
create table t1 (i int) engine=Connect table_type=XML option_list='xmlsup=libxml2';
Warnings:
Warning 1105 No file name. Table will use t1.xml
select * from information_schema.tables where create_options like '%table_type=XML%';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
Warnings:
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1286 Unknown storage engine 'InnoDB'
Warning 1296 Got error 174 'File t1.xml not found' from CONNECT
drop table t1;

View File

@@ -5,6 +5,8 @@ set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
@@ -33,11 +35,13 @@ DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (sec CHAR(10) NOT NULL FLAG=1, val CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=INI FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES ('sec1','val1');
connection user;
SELECT user();
user()
user@localhost
@@ -58,10 +62,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -73,6 +79,8 @@ UPDATE v1 SET val='val11';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
disconnect user;
connection default;
DROP VIEW v1;
DROP TABLE t1;
DROP USER user@localhost;

View File

@@ -1,3 +1,7 @@
connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
connection master;
connection slave;
SET GLOBAL time_zone='+1:00';
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
@@ -11,6 +15,7 @@ NULL NULL
#
# Testing errors
#
connection master;
SET GLOBAL time_zone='+1:00';
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown';
@@ -36,10 +41,14 @@ ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Unkn
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
connection slave;
ALTER TABLE t1 RENAME t1backup;
connection master;
SELECT * FROM t1;
ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Table 'test.t1' doesn't exist' from CONNECT
connection slave;
ALTER TABLE t1backup RENAME t1;
connection master;
DROP TABLE t1;
#
# Testing SELECT, etc.
@@ -108,6 +117,7 @@ NULL NULL
2 0
3 0
DROP TABLE t1;
connection slave;
DROP TABLE t1;
#
# Testing numeric data types
@@ -126,6 +136,7 @@ t1 CREATE TABLE `t1` (
`h` decimal(20,5) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
SHOW CREATE TABLE t1;
@@ -144,6 +155,7 @@ SELECT * FROM t1;
a b c d e f g h
100 3333 41235 1234567890 235000000000 3 3 3141.59265
DROP TABLE t1;
connection slave;
DROP TABLE t1;
#
# Testing character data types
@@ -159,6 +171,7 @@ INSERT INTO t1 VALUES('Welcome','Hello, World');
SELECT * FROM t1;
a b
Welcome Hello, World
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
SHOW CREATE TABLE t1;
@@ -171,6 +184,7 @@ SELECT * FROM t1;
a b
Welcome Hello, World
DROP TABLE t1;
connection slave;
DROP TABLE t1;
#
# Testing temporal data types
@@ -182,10 +196,10 @@ t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`e` year(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
INSERT IGNORE INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
Note 1265 Data truncated for column 'c' at row 1
@@ -193,6 +207,7 @@ Warning 1265 Data truncated for column 'e' at row 1
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC
CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root';
SHOW CREATE TABLE t1;
@@ -201,13 +216,15 @@ t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`e` year(4) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC'
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 11:45:23 10:45:23 2003-05-27 10:45:23 2003
DROP TABLE t1;
connection slave;
DROP TABLE t1;
SET GLOBAL time_zone=SYSTEM;
connection master;
SET GLOBAL time_zone=SYSTEM;

View File

@@ -0,0 +1,386 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
#
# Test the MONGO table type
#
CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CONNECTION='mongodb://localhost:27017' LRECL=4096
OPTION_LIST='Driver=Java,Version=2' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":"2014-03-03T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-09-11T00:00:00.000Z"},"grade":"A","score":6},{"date":{"$date":"2013-01-24T00:00:00.000Z"},"grade":"A","score":10},{"date":{"$date":"2011-11-23T00:00:00.000Z"},"grade":"A","score":9},{"date":{"$date":"2011-03-10T00:00:00.000Z"},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":"2014-12-30T00:00:00.000Z"},"grade":"A","score":8},{"date":{"$date":"2014-07-01T00:00:00.000Z"},"grade":"B","score":23},{"date":{"$date":"2013-04-30T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2012-05-08T00:00:00.000Z"},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.98513559999999,40.7676919],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":"2014-09-06T00:00:00.000Z"},"grade":"A","score":2},{"date":{"$date":"2013-07-22T00:00:00.000Z"},"grade":"A","score":11},{"date":{"$date":"2012-07-31T00:00:00.000Z"},"grade":"A","score":12},{"date":{"$date":"2011-12-29T00:00:00.000Z"},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=Java,Version=2' DATA_CHARSET=utf8 CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 256 256 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
grades 1 CHAR 0 0 0 1
grades_date 1 CHAR 256 256 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0
restaurant_id 1 CHAR 8 8 0 0
DROP TABLE t1;
#
# Explicit columns
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=2';
SELECT * FROM t1 LIMIT 10;
_id name cuisine borough restaurant_id
58ada47de5a51ddfcd5ed51c Morris Park Bake Shop Bakery Bronx 30075445
58ada47de5a51ddfcd5ed51d Wendy'S Hamburgers Brooklyn 30112340
58ada47de5a51ddfcd5ed51e Dj Reynolds Pub And Restaurant Irish Manhattan 30191841
58ada47de5a51ddfcd5ed51f Riviera Caterer American Brooklyn 40356018
58ada47de5a51ddfcd5ed520 Tov Kosher Kitchen Jewish/Kosher Queens 40356068
58ada47de5a51ddfcd5ed521 Brunos On The Boulevard American Queens 40356151
58ada47de5a51ddfcd5ed522 Kosher Island Jewish/Kosher Staten Island 40356442
58ada47de5a51ddfcd5ed523 Wilken'S Fine Food Delicatessen Brooklyn 40356483
58ada47de5a51ddfcd5ed524 Regina Caterers American Brooklyn 40356649
58ada47de5a51ddfcd5ed525 Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn 40356731
DROP TABLE t1;
#
# Test discovery
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
OPTION_LIST='Level=1,Driver=Java,Version=2' CONNECTION='mongodb://localhost:27017' LRECL=4096 DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
`grades` char(1) DEFAULT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8' `LRECL`=4096
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades grades_date grades_grade grades_score name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 -73.856077 Morris Park Ave 10462 Bronx Bakery 2 2014-03-03T00:00:00.000Z A 2 Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 -73.961704 Flatbush Avenue 11225 Brooklyn Hamburgers 2 2014-12-30T00:00:00.000Z A 8 Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 West 57 Street 10019 Manhattan Irish 2 2014-09-06T00:00:00.000Z A 2 Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 Stillwell Avenue 11224 Brooklyn American 2 2014-06-10T00:00:00.000Z A 5 Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 -73.8601152 63 Road 11374 Queens Jewish/Kosher 2 2014-11-24T00:00:00.000Z Z 20 Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants DATA_CHARSET=utf8
COLIST='{"grades":0}' OPTION_LIST='Driver=Java,Version=2,level=0' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 -73.856077 40.848447 Morris Park Ave 10462 Bronx Bakery Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 -73.961704 40.662942 Flatbush Avenue 11225 Brooklyn Hamburgers Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 40.7676919 West 57 Street 10019 Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 40.579505 Stillwell Avenue 11224 Brooklyn American Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 -73.8601152 40.7311739 63 Road 11374 Queens Jewish/Kosher Tov Kosher Kitchen 40356068
58ada47de5a51ddfcd5ed521 8825 -73.8803827 40.7643124 Astoria Boulevard 11369 Queens American Brunos On The Boulevard 40356151
58ada47de5a51ddfcd5ed522 2206 -74.1377286 40.6119572 Victory Boulevard 10314 Staten Island Jewish/Kosher Kosher Island 40356442
58ada47de5a51ddfcd5ed523 7114 -73.9068506 40.6199034 Avenue U 11234 Brooklyn Delicatessen Wilken'S Fine Food 40356483
58ada47de5a51ddfcd5ed524 6409 -74.00528899999999 40.628886 11 Avenue 11219 Brooklyn American Regina Caterers 40356649
58ada47de5a51ddfcd5ed525 1839 -73.9482609 40.6408271 Nostrand Avenue 11226 Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=2' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1 LIMIT 1;
_id 58ada47de5a51ddfcd5ed51c
name Morris Park Bake Shop
cuisine Bakery
borough Bronx
street Morris Park Ave
building 1007
zipcode 10462
grade A
score 2
date 1970-01-01
restaurant_id 30075445
SELECT name, street, score, date FROM t1 LIMIT 5;
name street score date
Morris Park Bake Shop Morris Park Ave 2 1970-01-01
Wendy'S Flatbush Avenue 8 1970-01-01
Dj Reynolds Pub And Restaurant West 57 Street 2 1970-01-01
Riviera Caterer Stillwell Avenue 5 1970-01-01
Tov Kosher Kitchen 63 Road 20 1970-01-01
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
name cuisine borough
Morris Park Bake Shop Bakery Bronx
Wendy'S Hamburgers Brooklyn
Dj Reynolds Pub And Restaurant Irish Manhattan
Riviera Caterer American Brooklyn
Kosher Island Jewish/Kosher Staten Island
Wilken'S Fine Food Delicatessen Brooklyn
Regina Caterers American Brooklyn
Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn
Wild Asia American Bronx
C & C Catering Service American Brooklyn
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
COUNT(*)
20687
SELECT * FROM t1 WHERE cuisine = 'English';
_id name cuisine borough street building zipcode grade score date restaurant_id
58ada47de5a51ddfcd5ed83d Tea And Sympathy English Manhattan Greenwich Avenue 108 10011 A 8 1970-01-01 40391531
58ada47de5a51ddfcd5ed85c Tartine English Manhattan West 11 Street 253 10014 A 11 1970-01-01 40392496
58ada47de5a51ddfcd5ee1f3 The Park Slope Chipshop English Brooklyn 5 Avenue 383 11215 B 17 1970-01-01 40816202
58ada47de5a51ddfcd5ee7e4 Pound And Pence English Manhattan Liberty Street 55 10005 A 7 1970-01-01 41022701
58ada47de5a51ddfcd5ee999 Chip Shop English Brooklyn Atlantic Avenue 129 11201 A 9 1970-01-01 41076583
58ada47ee5a51ddfcd5efe3f The Breslin Bar & Dining Room English Manhattan West 29 Street 16 10001 A 13 1970-01-01 41443706
58ada47ee5a51ddfcd5efe99 Highlands Restaurant English Manhattan West 10 Street 150 10014 A 12 1970-01-01 41448559
58ada47ee5a51ddfcd5f0413 The Fat Radish English Manhattan Orchard Street 17 10002 A 12 1970-01-01 41513545
58ada47ee5a51ddfcd5f0777 Jones Wood Foundry English Manhattan East 76 Street 401 10021 A 12 1970-01-01 41557377
58ada47ee5a51ddfcd5f0ea2 Whitehall English Manhattan Greenwich Avenue 19 10014 Z 15 1970-01-01 41625263
58ada47ee5a51ddfcd5f1004 The Churchill Tavern English Manhattan East 28 Street 45 10016 A 13 1970-01-01 41633327
58ada47ee5a51ddfcd5f13d5 The Monro English Brooklyn 5 Avenue 481 11215 A 7 1970-01-01 41660253
58ada47ee5a51ddfcd5f1454 The Cock & Bull English Manhattan West 45 Street 23 10036 A 7 1970-01-01 41664704
58ada47ee5a51ddfcd5f176e Dear Bushwick English Brooklyn Wilson Avenue 41 11237 A 12 1970-01-01 41690534
58ada47ee5a51ddfcd5f1e91 Snowdonia Pub English Queens 32 Street 34-55 11106 A 12 1970-01-01 50000290
58ada47ee5a51ddfcd5f2ddc Oscar'S Place English Manhattan Hudson Street 466 10014 A 10 1970-01-01 50011097
SELECT * FROM t1 WHERE score = building;
_id name cuisine borough street building zipcode grade score date restaurant_id
DROP TABLE t1;
#
# Specifying Filter
#
CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
OPTION_LIST='Driver=Java,Version=2' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT name FROM t1 WHERE borough = 'Queens';
name
La Baraka Restaurant
Air France Lounge
Tournesol
Winegasm
Cafe Henri
Bistro 33
Domaine Wine Bar
Cafe Triskell
Cannelle Patisserie
La Vie
Dirty Pierres Bistro
Fresca La Crepe
Bliss 46 Bistro
Bear
Cuisine By Claudette
Paris Baguette
The Baroness Bar
Francis Cafe
Madame Sou Sou
Crepe 'N' Tearia
Aperitif Bayside Llc
DROP TABLE t1;
#
# Testing pipeline
#
CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
OPTION_LIST='Driver=Java,Version=2,Pipeline=1' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1 LIMIT 10;
name borough date grade score
Tout Va Bien Manhattan 1970-01-01 01:33:34 B 15
Tout Va Bien Manhattan 1970-01-01 01:33:34 A 13
Tout Va Bien Manhattan 1970-01-01 01:33:33 C 36
Tout Va Bien Manhattan 1970-01-01 01:33:33 B 22
Tout Va Bien Manhattan 1970-01-01 01:33:32 C 36
Tout Va Bien Manhattan 1970-01-01 01:33:32 C 7
La Grenouille Manhattan 1970-01-01 01:33:34 A 10
La Grenouille Manhattan 1970-01-01 01:33:33 A 9
La Grenouille Manhattan 1970-01-01 01:33:32 A 13
Le Perigord Manhattan 1970-01-01 01:33:34 B 14
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
name grade score date
Bistro Sk A 10 1970-01-01 01:33:34
Bistro Sk A 12 1970-01-01 01:33:34
Bistro Sk B 18 1970-01-01 01:33:33
DROP TABLE t1;
#
# try level 2 discovery
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
COLIST='{"cuisine":0}' CONNECTION='mongodb://localhost:27017' LRECL=4096
OPTION_LIST='Driver=Java,level=2,version=2';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` double(18,16) DEFAULT NULL `FIELD_FORMAT`='address.coord.0',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`grades` char(1) DEFAULT NULL,
`grades_date` char(24) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2' `LRECL`=4096
SELECT name, borough, address_street, grades_score AS score FROM t1 WHERE grades_grade = 'B';
name borough address_street score
Le Gamin Brooklyn Vanderbilt Avenue 24
Bistro 33 Queens Ditmars Boulevard 15
Dirty Pierres Bistro Queens Station Square 22
Santos Anne Brooklyn Union Avenue 26
Le Paddock Brooklyn Prospect Avenue 17
La Crepe Et La Vie Brooklyn Foster Avenue 24
Francis Cafe Queens Ditmars Boulevard 19
DROP TABLE t1;
#
# try CRUD operations
#
false
CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll'
OPTION_LIST='Driver=Java,Version=2' CONNECTION='mongodb://localhost:27017' LRECL=4096;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
_id msg
0 NULL
1 One
2 Two
3 Three
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
_id msg
1 One
2 Deux
3 Three
DELETE FROM t1;
DROP TABLE t1;
true
#
# List states whose population is equal or more than 10 millions
#
false
CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=Java,Version=2' CONNECTION='mongodb://localhost:27017' LRECL=4096 DATA_CHARSET='utf8';
# Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
state totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
# Using a pipeline for grouping
CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$group":{"_id":"$state","totalPop":{"$sum":"$pop"}}},{"$match":{"totalPop":{"$gte":10000000}}},{"$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=Java,Version=2,Pipeline=1' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1;
_id totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
true
#
# Test making array
#
CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=2' CONNECTION='mongodb://localhost:27017' LRECL=4096;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
_id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
# Test array aggregation
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll'
COLIST='{"pipeline":[{"$project":{"_id":0,"item":1,"total":{"$sum":"$prices"},"average":{"$avg":"$prices"}}}]}'
OPTION_LIST='Driver=Java,Version=2,Pipeline=YES' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1;
item total average
journal 285 57.00
notebook 1368 456.00
paper 23 5.75
planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true

View File

@@ -0,0 +1,386 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
#
# Test the MONGO table type
#
CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CONNECTION='mongodb://localhost:27017' LRECL=4096
OPTION_LIST='Driver=Java,Version=3' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856077,40.848447],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.961704,40.662942],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.98513559999999,40.7676919],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=Java,Version=3' DATA_CHARSET=utf8 CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 256 256 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
grades 1 CHAR 0 0 0 1
grades_date 1 CHAR 256 256 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0
restaurant_id 1 CHAR 8 8 0 0
DROP TABLE t1;
#
# Explicit columns
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=3';
SELECT * FROM t1 LIMIT 10;
_id name cuisine borough restaurant_id
58ada47de5a51ddfcd5ed51c Morris Park Bake Shop Bakery Bronx 30075445
58ada47de5a51ddfcd5ed51d Wendy'S Hamburgers Brooklyn 30112340
58ada47de5a51ddfcd5ed51e Dj Reynolds Pub And Restaurant Irish Manhattan 30191841
58ada47de5a51ddfcd5ed51f Riviera Caterer American Brooklyn 40356018
58ada47de5a51ddfcd5ed520 Tov Kosher Kitchen Jewish/Kosher Queens 40356068
58ada47de5a51ddfcd5ed521 Brunos On The Boulevard American Queens 40356151
58ada47de5a51ddfcd5ed522 Kosher Island Jewish/Kosher Staten Island 40356442
58ada47de5a51ddfcd5ed523 Wilken'S Fine Food Delicatessen Brooklyn 40356483
58ada47de5a51ddfcd5ed524 Regina Caterers American Brooklyn 40356649
58ada47de5a51ddfcd5ed525 Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn 40356731
DROP TABLE t1;
#
# Test discovery
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
OPTION_LIST='Level=1,Driver=Java,Version=3' CONNECTION='mongodb://localhost:27017' LRECL=4096 DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
`grades` char(1) DEFAULT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8' `LRECL`=4096
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades grades_date grades_grade grades_score name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 -73.856077 Morris Park Ave 10462 Bronx Bakery 1 1393804800 A 2 Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 -73.961704 Flatbush Avenue 11225 Brooklyn Hamburgers 1 1419897600 A 8 Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 West 57 Street 10019 Manhattan Irish 1 1409961600 A 2 Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 Stillwell Avenue 11224 Brooklyn American 1 1402358400 A 5 Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 -73.8601152 63 Road 11374 Queens Jewish/Kosher 1 1416787200 Z 20 Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants DATA_CHARSET=utf8
COLIST='{"grades":0}' OPTION_LIST='Driver=Java,Version=3,level=0' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 -73.856077 40.848447 Morris Park Ave 10462 Bronx Bakery Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 -73.961704 40.662942 Flatbush Avenue 11225 Brooklyn Hamburgers Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 -73.98513559999999 40.7676919 West 57 Street 10019 Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 -73.98241999999999 40.579505 Stillwell Avenue 11224 Brooklyn American Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 -73.8601152 40.7311739 63 Road 11374 Queens Jewish/Kosher Tov Kosher Kitchen 40356068
58ada47de5a51ddfcd5ed521 8825 -73.8803827 40.7643124 Astoria Boulevard 11369 Queens American Brunos On The Boulevard 40356151
58ada47de5a51ddfcd5ed522 2206 -74.1377286 40.6119572 Victory Boulevard 10314 Staten Island Jewish/Kosher Kosher Island 40356442
58ada47de5a51ddfcd5ed523 7114 -73.9068506 40.6199034 Avenue U 11234 Brooklyn Delicatessen Wilken'S Fine Food 40356483
58ada47de5a51ddfcd5ed524 6409 -74.00528899999999 40.628886 11 Avenue 11219 Brooklyn American Regina Caterers 40356649
58ada47de5a51ddfcd5ed525 1839 -73.9482609 40.6408271 Nostrand Avenue 11226 Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=3' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1 LIMIT 1;
_id 58ada47de5a51ddfcd5ed51c
name Morris Park Bake Shop
cuisine Bakery
borough Bronx
street Morris Park Ave
building 1007
zipcode 10462
grade A
score 2
date 2014-03-03
restaurant_id 30075445
SELECT name, street, score, date FROM t1 LIMIT 5;
name street score date
Morris Park Bake Shop Morris Park Ave 2 2014-03-03
Wendy'S Flatbush Avenue 8 2014-12-30
Dj Reynolds Pub And Restaurant West 57 Street 2 2014-09-06
Riviera Caterer Stillwell Avenue 5 2014-06-10
Tov Kosher Kitchen 63 Road 20 2014-11-24
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
name cuisine borough
Morris Park Bake Shop Bakery Bronx
Wendy'S Hamburgers Brooklyn
Dj Reynolds Pub And Restaurant Irish Manhattan
Riviera Caterer American Brooklyn
Kosher Island Jewish/Kosher Staten Island
Wilken'S Fine Food Delicatessen Brooklyn
Regina Caterers American Brooklyn
Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn
Wild Asia American Bronx
C & C Catering Service American Brooklyn
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
COUNT(*)
20687
SELECT * FROM t1 WHERE cuisine = 'English';
_id name cuisine borough street building zipcode grade score date restaurant_id
58ada47de5a51ddfcd5ed83d Tea And Sympathy English Manhattan Greenwich Avenue 108 10011 A 8 2014-10-23 40391531
58ada47de5a51ddfcd5ed85c Tartine English Manhattan West 11 Street 253 10014 A 11 2014-08-14 40392496
58ada47de5a51ddfcd5ee1f3 The Park Slope Chipshop English Brooklyn 5 Avenue 383 11215 B 17 2014-09-29 40816202
58ada47de5a51ddfcd5ee7e4 Pound And Pence English Manhattan Liberty Street 55 10005 A 7 2014-02-11 41022701
58ada47de5a51ddfcd5ee999 Chip Shop English Brooklyn Atlantic Avenue 129 11201 A 9 2014-10-08 41076583
58ada47ee5a51ddfcd5efe3f The Breslin Bar & Dining Room English Manhattan West 29 Street 16 10001 A 13 2014-06-09 41443706
58ada47ee5a51ddfcd5efe99 Highlands Restaurant English Manhattan West 10 Street 150 10014 A 12 2014-10-22 41448559
58ada47ee5a51ddfcd5f0413 The Fat Radish English Manhattan Orchard Street 17 10002 A 12 2014-07-26 41513545
58ada47ee5a51ddfcd5f0777 Jones Wood Foundry English Manhattan East 76 Street 401 10021 A 12 2014-12-03 41557377
58ada47ee5a51ddfcd5f0ea2 Whitehall English Manhattan Greenwich Avenue 19 10014 Z 15 2015-01-16 41625263
58ada47ee5a51ddfcd5f1004 The Churchill Tavern English Manhattan East 28 Street 45 10016 A 13 2014-08-27 41633327
58ada47ee5a51ddfcd5f13d5 The Monro English Brooklyn 5 Avenue 481 11215 A 7 2014-06-03 41660253
58ada47ee5a51ddfcd5f1454 The Cock & Bull English Manhattan West 45 Street 23 10036 A 7 2014-08-07 41664704
58ada47ee5a51ddfcd5f176e Dear Bushwick English Brooklyn Wilson Avenue 41 11237 A 12 2014-12-27 41690534
58ada47ee5a51ddfcd5f1e91 Snowdonia Pub English Queens 32 Street 34-55 11106 A 12 2014-10-28 50000290
58ada47ee5a51ddfcd5f2ddc Oscar'S Place English Manhattan Hudson Street 466 10014 A 10 2014-08-18 50011097
SELECT * FROM t1 WHERE score = building;
_id name cuisine borough street building zipcode grade score date restaurant_id
DROP TABLE t1;
#
# Specifying Filter
#
CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
OPTION_LIST='Driver=Java,Version=3' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT name FROM t1 WHERE borough = 'Queens';
name
La Baraka Restaurant
Air France Lounge
Tournesol
Winegasm
Cafe Henri
Bistro 33
Domaine Wine Bar
Cafe Triskell
Cannelle Patisserie
La Vie
Dirty Pierres Bistro
Fresca La Crepe
Bliss 46 Bistro
Bear
Cuisine By Claudette
Paris Baguette
The Baroness Bar
Francis Cafe
Madame Sou Sou
Crepe 'N' Tearia
Aperitif Bayside Llc
DROP TABLE t1;
#
# Testing pipeline
#
CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
OPTION_LIST='Driver=Java,Version=3,Pipeline=1' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1 LIMIT 10;
name borough date grade score
Tout Va Bien Manhattan 2014-11-10 01:00:00 B 15
Tout Va Bien Manhattan 2014-04-03 02:00:00 A 13
Tout Va Bien Manhattan 2013-07-17 02:00:00 C 36
Tout Va Bien Manhattan 2013-02-06 01:00:00 B 22
Tout Va Bien Manhattan 2012-07-16 02:00:00 C 36
Tout Va Bien Manhattan 2012-03-08 01:00:00 C 7
La Grenouille Manhattan 2014-04-09 02:00:00 A 10
La Grenouille Manhattan 2013-03-05 01:00:00 A 9
La Grenouille Manhattan 2012-02-02 01:00:00 A 13
Le Perigord Manhattan 2014-07-14 02:00:00 B 14
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
name grade score date
Bistro Sk A 10 2014-11-21 01:00:00
Bistro Sk A 12 2014-02-19 01:00:00
Bistro Sk B 18 2013-06-12 02:00:00
DROP TABLE t1;
#
# try level 2 discovery
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
COLIST='{"cuisine":0}' CONNECTION='mongodb://localhost:27017' LRECL=4096
OPTION_LIST='Driver=Java,level=2,version=3';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` double(18,16) DEFAULT NULL `FIELD_FORMAT`='address.coord.0',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`grades` char(1) DEFAULT NULL,
`grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3' `LRECL`=4096
SELECT name, borough, address_street, grades_score AS score FROM t1 WHERE grades_grade = 'B';
name borough address_street score
Le Gamin Brooklyn Vanderbilt Avenue 24
Bistro 33 Queens Ditmars Boulevard 15
Dirty Pierres Bistro Queens Station Square 22
Santos Anne Brooklyn Union Avenue 26
Le Paddock Brooklyn Prospect Avenue 17
La Crepe Et La Vie Brooklyn Foster Avenue 24
Francis Cafe Queens Ditmars Boulevard 19
DROP TABLE t1;
#
# try CRUD operations
#
false
CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll'
OPTION_LIST='Driver=Java,Version=3' CONNECTION='mongodb://localhost:27017' LRECL=4096;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
_id msg
0 NULL
1 One
2 Two
3 Three
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
_id msg
1 One
2 Deux
3 Three
DELETE FROM t1;
DROP TABLE t1;
true
#
# List states whose population is equal or more than 10 millions
#
false
CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=Java,Version=3' CONNECTION='mongodb://localhost:27017' LRECL=4096 DATA_CHARSET='utf8';
# Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
state totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
# Using a pipeline for grouping
CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$group":{"_id":"$state","totalPop":{"$sum":"$pop"}}},{"$match":{"totalPop":{"$gte":10000000}}},{"$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=Java,Version=3,Pipeline=1' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1;
_id totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
true
#
# Test making array
#
CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=3' CONNECTION='mongodb://localhost:27017' LRECL=4096;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
_id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
# Test array aggregation
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll'
COLIST='{"pipeline":[{"$project":{"_id":0,"item":1,"total":{"$sum":"$prices"},"average":{"$avg":"$prices"}}}]}'
OPTION_LIST='Driver=Java,Version=3,Pipeline=YES' CONNECTION='mongodb://localhost:27017' LRECL=4096;
SELECT * FROM t1;
item total average
journal 285 57.00
notebook 1368 456.00
paper 23 5.75
planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true

View File

@@ -0,0 +1,385 @@
#
# Test the MONGO table type
#
CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CONNECTION='mongodb://localhost:27017' LRECL=1024
OPTION_LIST='Driver=C,Version=0' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris Park Ave","zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris Park Bake Shop","restaurant_id":"30075445"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue","zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57 Street","zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj Reynolds Pub And Restaurant","restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=C,Version=0' DATA_CHARSET=utf8 CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Jpath
_id 1 CHAR 24 24 0 0 _id
address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 256 256 0 1 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
grades 1 CHAR 0 0 0 1
grades_date 1 CHAR 256 256 0 1 grades.0.date
grades_grade 1 CHAR 14 14 0 1 grades.0.grade
grades_score 5 BIGINT 2 2 0 1 grades.0.score
name 1 CHAR 98 98 0 0
restaurant_id 1 CHAR 8 8 0 0
DROP TABLE t1;
#
# Explicit columns
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=C,Version=0';
SELECT * FROM t1 LIMIT 10;
_id name cuisine borough restaurant_id
58ada47de5a51ddfcd5ed51c Morris Park Bake Shop Bakery Bronx 30075445
58ada47de5a51ddfcd5ed51d Wendy'S Hamburgers Brooklyn 30112340
58ada47de5a51ddfcd5ed51e Dj Reynolds Pub And Restaurant Irish Manhattan 30191841
58ada47de5a51ddfcd5ed51f Riviera Caterer American Brooklyn 40356018
58ada47de5a51ddfcd5ed520 Tov Kosher Kitchen Jewish/Kosher Queens 40356068
58ada47de5a51ddfcd5ed521 Brunos On The Boulevard American Queens 40356151
58ada47de5a51ddfcd5ed522 Kosher Island Jewish/Kosher Staten Island 40356442
58ada47de5a51ddfcd5ed523 Wilken'S Fine Food Delicatessen Brooklyn 40356483
58ada47de5a51ddfcd5ed524 Regina Caterers American Brooklyn 40356649
58ada47de5a51ddfcd5ed525 Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn 40356731
DROP TABLE t1;
#
# Test discovery
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
OPTION_LIST='Level=1,Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` varchar(256) DEFAULT NULL `FIELD_FORMAT`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
`grades` char(1) DEFAULT NULL,
`grades_date` varchar(256) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=C,Version=0' `DATA_CHARSET`='utf8' `LRECL`=1024
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades grades_date grades_grade grades_score name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 -73.856076999999999089 Morris Park Ave 10462 Bronx Bakery 1 1393804800 A 2 Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 -73.96170399999999745 Flatbush Avenue 11225 Brooklyn Hamburgers 1 1419897600 A 8 Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 -73.985135599999992451 West 57 Street 10019 Manhattan Irish 1 1409961600 A 2 Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 -73.982419999999990523 Stillwell Avenue 11224 Brooklyn American 1 1402358400 A 5 Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 -73.860115199999995639 63 Road 11374 Queens Jewish/Kosher 1 1416787200 Z 20 Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants DATA_CHARSET=utf8
COLIST='{"projection":{"grades":0}}' OPTION_LIST='Driver=C,Version=0,level=0' CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 -73.856076999999999089 40.848447000000000173 Morris Park Ave 10462 Bronx Bakery Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 -73.96170399999999745 40.66294200000000103 Flatbush Avenue 11225 Brooklyn Hamburgers Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 -73.985135599999992451 40.767691900000002647 West 57 Street 10019 Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 -73.982419999999990523 40.579504999999997494 Stillwell Avenue 11224 Brooklyn American Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 -73.860115199999995639 40.731173900000001709 63 Road 11374 Queens Jewish/Kosher Tov Kosher Kitchen 40356068
58ada47de5a51ddfcd5ed521 8825 -73.880382699999998408 40.764312400000001446 Astoria Boulevard 11369 Queens American Brunos On The Boulevard 40356151
58ada47de5a51ddfcd5ed522 2206 -74.137728600000002643 40.611957199999999091 Victory Boulevard 10314 Staten Island Jewish/Kosher Kosher Island 40356442
58ada47de5a51ddfcd5ed523 7114 -73.906850599999998508 40.619903399999998328 Avenue U 11234 Brooklyn Delicatessen Wilken'S Fine Food 40356483
58ada47de5a51ddfcd5ed524 6409 -74.005288999999990551 40.628886000000001388 11 Avenue 11219 Brooklyn American Regina Caterers 40356649
58ada47de5a51ddfcd5ed525 1839 -73.948260899999993967 40.640827100000002758 Nostrand Avenue 11226 Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT * FROM t1 LIMIT 1;
_id 58ada47de5a51ddfcd5ed51c
name Morris Park Bake Shop
cuisine Bakery
borough Bronx
street Morris Park Ave
building 1007
zipcode 10462
grade A
score 2
date 2014-03-03
restaurant_id 30075445
SELECT name, street, score, date FROM t1 LIMIT 5;
name street score date
Morris Park Bake Shop Morris Park Ave 2 2014-03-03
Wendy'S Flatbush Avenue 8 2014-12-30
Dj Reynolds Pub And Restaurant West 57 Street 2 2014-09-06
Riviera Caterer Stillwell Avenue 5 2014-06-10
Tov Kosher Kitchen 63 Road 20 2014-11-24
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
name cuisine borough
Morris Park Bake Shop Bakery Bronx
Wendy'S Hamburgers Brooklyn
Dj Reynolds Pub And Restaurant Irish Manhattan
Riviera Caterer American Brooklyn
Kosher Island Jewish/Kosher Staten Island
Wilken'S Fine Food Delicatessen Brooklyn
Regina Caterers American Brooklyn
Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn
Wild Asia American Bronx
C & C Catering Service American Brooklyn
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
COUNT(*)
20687
SELECT * FROM t1 WHERE cuisine = 'English';
_id name cuisine borough street building zipcode grade score date restaurant_id
58ada47de5a51ddfcd5ed83d Tea And Sympathy English Manhattan Greenwich Avenue 108 10011 A 8 2014-10-23 40391531
58ada47de5a51ddfcd5ed85c Tartine English Manhattan West 11 Street 253 10014 A 11 2014-08-14 40392496
58ada47de5a51ddfcd5ee1f3 The Park Slope Chipshop English Brooklyn 5 Avenue 383 11215 B 17 2014-09-29 40816202
58ada47de5a51ddfcd5ee7e4 Pound And Pence English Manhattan Liberty Street 55 10005 A 7 2014-02-11 41022701
58ada47de5a51ddfcd5ee999 Chip Shop English Brooklyn Atlantic Avenue 129 11201 A 9 2014-10-08 41076583
58ada47ee5a51ddfcd5efe3f The Breslin Bar & Dining Room English Manhattan West 29 Street 16 10001 A 13 2014-06-09 41443706
58ada47ee5a51ddfcd5efe99 Highlands Restaurant English Manhattan West 10 Street 150 10014 A 12 2014-10-22 41448559
58ada47ee5a51ddfcd5f0413 The Fat Radish English Manhattan Orchard Street 17 10002 A 12 2014-07-26 41513545
58ada47ee5a51ddfcd5f0777 Jones Wood Foundry English Manhattan East 76 Street 401 10021 A 12 2014-12-03 41557377
58ada47ee5a51ddfcd5f0ea2 Whitehall English Manhattan Greenwich Avenue 19 10014 Z 15 2015-01-16 41625263
58ada47ee5a51ddfcd5f1004 The Churchill Tavern English Manhattan East 28 Street 45 10016 A 13 2014-08-27 41633327
58ada47ee5a51ddfcd5f13d5 The Monro English Brooklyn 5 Avenue 481 11215 A 7 2014-06-03 41660253
58ada47ee5a51ddfcd5f1454 The Cock & Bull English Manhattan West 45 Street 23 10036 A 7 2014-08-07 41664704
58ada47ee5a51ddfcd5f176e Dear Bushwick English Brooklyn Wilson Avenue 41 11237 A 12 2014-12-27 41690534
58ada47ee5a51ddfcd5f1e91 Snowdonia Pub English Queens 32 Street 34-55 11106 A 12 2014-10-28 50000290
58ada47ee5a51ddfcd5f2ddc Oscar'S Place English Manhattan Hudson Street 466 10014 A 10 2014-08-18 50011097
SELECT * FROM t1 WHERE score = building;
_id name cuisine borough street building zipcode grade score date restaurant_id
DROP TABLE t1;
#
# Specifying Filter
#
CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
OPTION_LIST='Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT name FROM t1 WHERE borough = 'Queens';
name
La Baraka Restaurant
Air France Lounge
Tournesol
Winegasm
Cafe Henri
Bistro 33
Domaine Wine Bar
Cafe Triskell
Cannelle Patisserie
La Vie
Dirty Pierres Bistro
Fresca La Crepe
Bliss 46 Bistro
Bear
Cuisine By Claudette
Paris Baguette
The Baroness Bar
Francis Cafe
Madame Sou Sou
Crepe 'N' Tearia
Aperitif Bayside Llc
DROP TABLE t1;
#
# Testing pipeline
#
CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
OPTION_LIST='Driver=C,Version=0,Pipeline=1' CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT * FROM t1 LIMIT 10;
name borough date grade score
Tout Va Bien Manhattan 2014-11-10 01:00:00 B 15
Tout Va Bien Manhattan 2014-04-03 02:00:00 A 13
Tout Va Bien Manhattan 2013-07-17 02:00:00 C 36
Tout Va Bien Manhattan 2013-02-06 01:00:00 B 22
Tout Va Bien Manhattan 2012-07-16 02:00:00 C 36
Tout Va Bien Manhattan 2012-03-08 01:00:00 C 7
La Grenouille Manhattan 2014-04-09 02:00:00 A 10
La Grenouille Manhattan 2013-03-05 01:00:00 A 9
La Grenouille Manhattan 2012-02-02 01:00:00 A 13
Le Perigord Manhattan 2014-07-14 02:00:00 B 14
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
name grade score date
Bistro Sk A 10 2014-11-21 01:00:00
Bistro Sk A 12 2014-02-19 01:00:00
Bistro Sk B 18 2013-06-12 02:00:00
DROP TABLE t1;
#
# try level 2 discovery
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
COLIST='{"projection":{"cuisine":0}}' CONNECTION='mongodb://localhost:27017' LRECL=1024
OPTION_LIST='Driver=C,level=2,version=0';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL `FIELD_FORMAT`='_id',
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` double(23,20) DEFAULT NULL `FIELD_FORMAT`='address.coord.0',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`grades` char(1) DEFAULT NULL,
`grades_date` bigint(13) DEFAULT NULL `FIELD_FORMAT`='grades.0.date',
`grades_grade` char(14) DEFAULT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_score` bigint(2) DEFAULT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mongodb://localhost:27017' `TABLE_TYPE`='JSON' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0' `LRECL`=1024
SELECT name, borough, address_street, grades_score AS score FROM t1 WHERE grades_grade = 'B';
name borough address_street score
Le Gamin Brooklyn Vanderbilt Avenue 24
Bistro 33 Queens Ditmars Boulevard 15
Dirty Pierres Bistro Queens Station Square 22
Santos Anne Brooklyn Union Avenue 26
Le Paddock Brooklyn Prospect Avenue 17
La Crepe Et La Vie Brooklyn Foster Avenue 24
Francis Cafe Queens Ditmars Boulevard 19
DROP TABLE t1;
#
# try CRUD operations
#
false
CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll'
OPTION_LIST='Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' LRECL=1024;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
_id msg
0 NULL
1 One
2 Two
3 Three
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
_id msg
1 One
2 Deux
3 Three
DELETE FROM t1;
DROP TABLE t1;
true
#
# List states whose population is equal or more than 10 millions
#
false
CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET='utf8';
# Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
state totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
# Using a pipeline for grouping
CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$group":{"_id":"$state","totalPop":{"$sum":"$pop"}}},{"$match":{"totalPop":{"$gte":10000000}}},{"$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=C,Version=0,Pipeline=1' CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT * FROM t1;
_id totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
true
#
# Test making array
#
CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=C,Version=0' CONNECTION='mongodb://localhost:27017' LRECL=1024;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
_id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
4 planner 25 71 44 27 NULL
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
# Test array aggregation
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=JSON TABNAME='testcoll'
COLIST='{"pipeline":[{"$project":{"_id":0,"item":1,"total":{"$sum":"$prices"},"average":{"$avg":"$prices"}}}]}'
OPTION_LIST='Driver=C,Version=0,Pipeline=YES' CONNECTION='mongodb://localhost:27017' LRECL=1024;
SELECT * FROM t1;
item total average
journal 285 57.00
notebook 1368 456.00
paper 23 5.75
planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true

View File

@@ -608,7 +608,7 @@ JsonGet_String(Json_File('test/fx.json'), '1.*')
{"_id":6,"type":"car","item":"roadster","mileage":56000,"ratings":[6,9]}
SELECT JsonGet_String(Json_File('test/fx.json'), '1');
JsonGet_String(Json_File('test/fx.json'), '1')
6 car roadster 56000 <null>
6 car roadster 56000 6 9
SELECT JsonGet_Int(Json_File('test/fx.json'), '1.mileage') AS Mileage;
Mileage
56000

View File

@@ -0,0 +1,378 @@
#
# Test the MONGO table type
#
CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Driver=C,Version=0' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51c"},"address":{"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris ParkAve", "zipcode":"10462"},"borough":"Bronx","cuisine":"Bakery","grades":[{"date":{"$date":1393804800000},"grade":"A","score":2},{"date":{"$date":1378857600000},"grade":"A","score":6},{"date":{"$date":1358985600000},"grade":"A","score":10},{"date":{"$date":1322006400000},"grade":"A","score":9},{"date":{"$date":1299715200000},"grade":"B","score":14}],"name":"Morris ParkBakeShop", "restaurant_id":"30075445"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51d"},"address":{"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue", "zipcode":"11225"},"borough":"Brooklyn","cuisine":"Hamburgers","grades":[{"date":{"$date":1419897600000},"grade":"A","score":8},{"date":{"$date":1404172800000},"grade":"B","score":23},{"date":{"$date":1367280000000},"grade":"A","score":12},{"date":{"$date":1336435200000},"grade":"A","score":12}],"name":"Wendy'S","restaurant_id":"30112340"}
{"_id":{"$oid":"58ada47de5a51ddfcd5ed51e"},"address":{"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57Street", "zipcode":"10019"},"borough":"Manhattan","cuisine":"Irish","grades":[{"date":{"$date":1409961600000},"grade":"A","score":2},{"date":{"$date":1374451200000},"grade":"A","score":11},{"date":{"$date":1343692800000},"grade":"A","score":12},{"date":{"$date":1325116800000},"grade":"A","score":12}],"name":"Dj ReynoldsPubAndRestaurant", "restaurant_id":"30191841"}
DROP TABLE t1;
#
# Test catfunc
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=C,Version=0' DATA_CHARSET=utf8 ;
SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Bpath
_id 1 CHAR 24 24 0 0
address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 512 512 0 0 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
grades_0 1 CHAR 512 512 0 1 grades.0
name 1 CHAR 98 98 0 0
restaurant_id 1 CHAR 8 8 0 0
DROP TABLE t1;
#
# Explicit columns
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=C,Version=0';
SELECT * FROM t1 LIMIT 10;
_id name cuisine borough restaurant_id
58ada47de5a51ddfcd5ed51c Morris Park Bake Shop Bakery Bronx 30075445
58ada47de5a51ddfcd5ed51d Wendy'S Hamburgers Brooklyn 30112340
58ada47de5a51ddfcd5ed51e Dj Reynolds Pub And Restaurant Irish Manhattan 30191841
58ada47de5a51ddfcd5ed51f Riviera Caterer American Brooklyn 40356018
58ada47de5a51ddfcd5ed520 Tov Kosher Kitchen Jewish/Kosher Queens 40356068
58ada47de5a51ddfcd5ed521 Brunos On The Boulevard American Queens 40356151
58ada47de5a51ddfcd5ed522 Kosher Island Jewish/Kosher Staten Island 40356442
58ada47de5a51ddfcd5ed523 Wilken'S Fine Food Delicatessen Brooklyn 40356483
58ada47de5a51ddfcd5ed524 Regina Caterers American Brooklyn 40356649
58ada47de5a51ddfcd5ed525 Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn 40356731
DROP TABLE t1;
#
# Test discovery
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Level=1,Driver=C,Version=0' DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` varchar(512) NOT NULL `FIELD_FORMAT`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
`grades_0` varchar(512) DEFAULT NULL `FIELD_FORMAT`='grades.0',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=C,Version=0' `DATA_CHARSET`='utf8'
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 Morris Park Ave 10462 Bronx Bakery {"date":{"$date":1393804800000},"grade":"A","score":2} Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 Flatbush Avenue 11225 Brooklyn Hamburgers {"date":{"$date":1419897600000},"grade":"A","score":8} Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 West 57 Street 10019 Manhattan Irish {"date":{"$date":1409961600000},"grade":"A","score":2} Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 Stillwell Avenue 11224 Brooklyn American {"date":{"$date":1402358400000},"grade":"A","score":5} Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 63 Road 11374 Queens Jewish/Kosher {"date":{"$date":1416787200000},"grade":"Z","score":20} Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET=utf8
COLIST='{"projection":{"grades":0}}' OPTION_LIST='Driver=C,Version=0,level=0' ;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
58ada47de5a51ddfcd5ed51c {"building":"1007","coord":[-73.856076999999999089,40.848447000000000173],"street":"Morris ParkAve", "zipcode":"10462"} Bronx Bakery Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d {"building":"469","coord":[-73.96170399999999745,40.66294200000000103],"street":"Flatbush Avenue", "zipcode":"11225"} Brooklyn Hamburgers Wendy'S 30112340
58ada47de5a51ddfcd5ed51e {"building":"351","coord":[-73.985135599999992451,40.767691900000002647],"street":"West 57Street", "zipcode":"10019"} Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f {"building":"2780","coord":[-73.982419999999990523,40.579504999999997494],"street":"Stillwell Avenue", "zipcode":"11224"} Brooklyn American Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 {"building":"97-22","coord":[-73.860115199999995639,40.731173900000001709],"street":"63 Road", "zipcode":"11374"} Queens Jewish/Kosher Tov Kosher Kitchen 40356068
58ada47de5a51ddfcd5ed521 {"building":"8825","coord":[-73.880382699999998408,40.764312400000001446],"street":"Astoria Boulevard", "zipcode":"11369"} Queens American Brunos On The Boulevard 40356151
58ada47de5a51ddfcd5ed522 {"building":"2206","coord":[-74.137728600000002643,40.611957199999999091],"street":"Victory Boulevard", "zipcode":"10314"} Staten Island Jewish/Kosher Kosher Island 40356442
58ada47de5a51ddfcd5ed523 {"building":"7114","coord":[-73.906850599999998508,40.619903399999998328],"street":"Avenue U", "zipcode":"11234"} Brooklyn Delicatessen Wilken'S Fine Food 40356483
58ada47de5a51ddfcd5ed524 {"building":"6409","coord":[-74.005288999999990551,40.628886000000001388],"street":"11 Avenue", "zipcode":"11219"} Brooklyn American Regina Caterers 40356649
58ada47de5a51ddfcd5ed525 {"building":"1839","coord":[-73.948260899999993967,40.640827100000002758],"street":"Nostrand Avenue", "zipcode":"11226"} Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=C,Version=0' ;
SELECT * FROM t1 LIMIT 1;
_id 58ada47de5a51ddfcd5ed51c
name Morris Park Bake Shop
cuisine Bakery
borough Bronx
street Morris Park Ave
building 1007
zipcode 10462
grade A
score 2
date 2014-03-03
restaurant_id 30075445
SELECT name, street, score, date FROM t1 LIMIT 5;
name street score date
Morris Park Bake Shop Morris Park Ave 2 2014-03-03
Wendy'S Flatbush Avenue 8 2014-12-30
Dj Reynolds Pub And Restaurant West 57 Street 2 2014-09-06
Riviera Caterer Stillwell Avenue 5 2014-06-10
Tov Kosher Kitchen 63 Road 20 2014-11-24
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
name cuisine borough
Morris Park Bake Shop Bakery Bronx
Wendy'S Hamburgers Brooklyn
Dj Reynolds Pub And Restaurant Irish Manhattan
Riviera Caterer American Brooklyn
Kosher Island Jewish/Kosher Staten Island
Wilken'S Fine Food Delicatessen Brooklyn
Regina Caterers American Brooklyn
Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn
Wild Asia American Bronx
C & C Catering Service American Brooklyn
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
COUNT(*)
20687
SELECT * FROM t1 WHERE cuisine = 'English';
_id name cuisine borough street building zipcode grade score date restaurant_id
58ada47de5a51ddfcd5ed83d Tea And Sympathy English Manhattan Greenwich Avenue 108 10011 A 8 2014-10-23 40391531
58ada47de5a51ddfcd5ed85c Tartine English Manhattan West 11 Street 253 10014 A 11 2014-08-14 40392496
58ada47de5a51ddfcd5ee1f3 The Park Slope Chipshop English Brooklyn 5 Avenue 383 11215 B 17 2014-09-29 40816202
58ada47de5a51ddfcd5ee7e4 Pound And Pence English Manhattan Liberty Street 55 10005 A 7 2014-02-11 41022701
58ada47de5a51ddfcd5ee999 Chip Shop English Brooklyn Atlantic Avenue 129 11201 A 9 2014-10-08 41076583
58ada47ee5a51ddfcd5efe3f The Breslin Bar & Dining Room English Manhattan West 29 Street 16 10001 A 13 2014-06-09 41443706
58ada47ee5a51ddfcd5efe99 Highlands Restaurant English Manhattan West 10 Street 150 10014 A 12 2014-10-22 41448559
58ada47ee5a51ddfcd5f0413 The Fat Radish English Manhattan Orchard Street 17 10002 A 12 2014-07-26 41513545
58ada47ee5a51ddfcd5f0777 Jones Wood Foundry English Manhattan East 76 Street 401 10021 A 12 2014-12-03 41557377
58ada47ee5a51ddfcd5f0ea2 Whitehall English Manhattan Greenwich Avenue 19 10014 Z 15 2015-01-16 41625263
58ada47ee5a51ddfcd5f1004 The Churchill Tavern English Manhattan East 28 Street 45 10016 A 13 2014-08-27 41633327
58ada47ee5a51ddfcd5f13d5 The Monro English Brooklyn 5 Avenue 481 11215 A 7 2014-06-03 41660253
58ada47ee5a51ddfcd5f1454 The Cock & Bull English Manhattan West 45 Street 23 10036 A 7 2014-08-07 41664704
58ada47ee5a51ddfcd5f176e Dear Bushwick English Brooklyn Wilson Avenue 41 11237 A 12 2014-12-27 41690534
58ada47ee5a51ddfcd5f1e91 Snowdonia Pub English Queens 32 Street 34-55 11106 A 12 2014-10-28 50000290
58ada47ee5a51ddfcd5f2ddc Oscar'S Place English Manhattan Hudson Street 466 10014 A 10 2014-08-18 50011097
SELECT * FROM t1 WHERE score = building;
_id name cuisine borough street building zipcode grade score date restaurant_id
DROP TABLE t1;
#
# Specifying Filter
#
CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
OPTION_LIST='Driver=C,Version=0' ;
SELECT name FROM t1 WHERE borough = 'Queens';
name
La Baraka Restaurant
Air France Lounge
Tournesol
Winegasm
Cafe Henri
Bistro 33
Domaine Wine Bar
Cafe Triskell
Cannelle Patisserie
La Vie
Dirty Pierres Bistro
Fresca La Crepe
Bliss 46 Bistro
Bear
Cuisine By Claudette
Paris Baguette
The Baroness Bar
Francis Cafe
Madame Sou Sou
Crepe 'N' Tearia
Aperitif Bayside Llc
DROP TABLE t1;
#
# Testing pipeline
#
CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
OPTION_LIST='Driver=C,Version=0,Pipeline=1' ;
SELECT * FROM t1 LIMIT 10;
name borough date grade score
Tout Va Bien Manhattan 2014-11-10 01:00:00 B 15
Tout Va Bien Manhattan 2014-04-03 02:00:00 A 13
Tout Va Bien Manhattan 2013-07-17 02:00:00 C 36
Tout Va Bien Manhattan 2013-02-06 01:00:00 B 22
Tout Va Bien Manhattan 2012-07-16 02:00:00 C 36
Tout Va Bien Manhattan 2012-03-08 01:00:00 C 7
La Grenouille Manhattan 2014-04-09 02:00:00 A 10
La Grenouille Manhattan 2013-03-05 01:00:00 A 9
La Grenouille Manhattan 2012-02-02 01:00:00 A 13
Le Perigord Manhattan 2014-07-14 02:00:00 B 14
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
name grade score date
Bistro Sk A 10 2014-11-21 01:00:00
Bistro Sk A 12 2014-02-19 01:00:00
Bistro Sk B 18 2013-06-12 02:00:00
DROP TABLE t1;
#
# try level 2 discovery
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
COLIST='{"projection":{"cuisine":0}}'
OPTION_LIST='Driver=C,level=2,version=0';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
`address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord_0` double(12,6) NOT NULL `FIELD_FORMAT`='address.coord.0',
`address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date',
`grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_0_score` int(11) NOT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"projection":{"cuisine":0}}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=C,level=2,version=0'
SELECT name, borough, address_street, grades_0_score AS score FROM t1 WHERE grades_0_grade = 'B';
name borough address_street score
Le Gamin Brooklyn Vanderbilt Avenue 24
Bistro 33 Queens Ditmars Boulevard 15
Dirty Pierres Bistro Queens Station Square 22
Santos Anne Brooklyn Union Avenue 26
Le Paddock Brooklyn Prospect Avenue 17
La Crepe Et La Vie Brooklyn Foster Avenue 24
Francis Cafe Queens Ditmars Boulevard 19
DROP TABLE t1;
#
# try CRUD operations
#
false
CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll'
OPTION_LIST='Driver=C,Version=0' ;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
_id msg
0 NULL
1 One
2 Two
3 Three
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
_id msg
1 One
2 Deux
3 Three
DELETE FROM t1;
DROP TABLE t1;
true
#
# List states whose population is equal or more than 10 millions
#
false
CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=C,Version=0' DATA_CHARSET='utf8';
# Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
state totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
# Using a pipeline for grouping
CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$group":{"_id":"$state","totalPop":{"$sum":"$pop"}}},{"$match":{"totalPop":{"$gte":10000000}}},{"$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=C,Version=0,Pipeline=1' ;
SELECT * FROM t1;
_id totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
true
#
# Test making array
#
CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=C,Version=0' ;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
_id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
# Test array aggregation
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll'
COLIST='{"pipeline":[{"$project":{"_id":0,"item":1,"total":{"$sum":"$prices"},"average":{"$avg":"$prices"}}}]}'
OPTION_LIST='Driver=C,Version=0,Pipeline=YES' ;
SELECT * FROM t1;
item total average
journal 285 57.000000
notebook 1368 456.000000
paper 23 5.750000
planner 167 41.750000
postcard 23 5.750000
DROP TABLE t1;
true

View File

@@ -0,0 +1,379 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo2.jar';
#
# Test the MONGO table type
#
CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Driver=Java,Version=2' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
{ "_id" : { "$oid" : "58ada47de5a51ddfcd5ed51c"} , "address" : { "building" : "1007" , "coord" : [ -73.856077 , 40.848447] , "street" : "Morris Park Ave" , "zipcode" : "10462"} , "borough" : "Bronx" , "cuisine" : "Bakery" , "grades" : [ { "date" : { "$date" : "2014-03-03T00:00:00.000Z"} , "grade" : "A" , "score" : 2} , { "date" : { "$date" : "2013-09-11T00:00:00.000Z"} , "grade" : "A" , "score" : 6} , { "date" : { "$date" : "2013-01-24T00:00:00.000Z"} , "grade" : "A" , "score" : 10} , { "date" : { "$date" : "2011-11-23T00:00:00.000Z"} , "grade" : "A" , "score" : 9} , { "date" : { "$date" : "2011-03-10T00:00:00.000Z"} , "grade" : "B" , "score" : 14}] , "name" : "Morris Park Bake Shop" , "restaurant_id" : "30075445"}
{ "_id" : { "$oid" : "58ada47de5a51ddfcd5ed51d"} , "address" : { "building" : "469" , "coord" : [ -73.961704 , 40.662942] , "street" : "Flatbush Avenue" , "zipcode" : "11225"} , "borough" : "Brooklyn" , "cuisine" : "Hamburgers" , "grades" : [ { "date" : { "$date" : "2014-12-30T00:00:00.000Z"} , "grade" : "A" , "score" : 8} , { "date" : { "$date" : "2014-07-01T00:00:00.000Z"} , "grade" : "B" , "score" : 23} , { "date" : { "$date" : "2013-04-30T00:00:00.000Z"} , "grade" : "A" , "score" : 12} , { "date" : { "$date" : "2012-05-08T00:00:00.000Z"} , "grade" : "A" , "score" : 12}] , "name" : "Wendy'S" , "restaurant_id" : "30112340"}
{ "_id" : { "$oid" : "58ada47de5a51ddfcd5ed51e"} , "address" : { "building" : "351" , "coord" : [ -73.98513559999999 , 40.7676919] , "street" : "West 57 Street" , "zipcode" : "10019"} , "borough" : "Manhattan" , "cuisine" : "Irish" , "grades" : [ { "date" : { "$date" : "2014-09-06T00:00:00.000Z"} , "grade" : "A" , "score" : 2} , { "date" : { "$date" : "2013-07-22T00:00:00.000Z"} , "grade" : "A" , "score" : 11} , { "date" : { "$date" : "2012-07-31T00:00:00.000Z"} , "grade" : "A" , "score" : 12} , { "date" : { "$date" : "2011-12-29T00:00:00.000Z"} , "grade" : "A" , "score" : 12}] , "name" : "Dj Reynolds Pub And Restaurant" , "restaurant_id" : "30191841"}
DROP TABLE t1;
#
# Test catfunc
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=Java,Version=2' DATA_CHARSET=utf8 ;
SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Bpath
_id 1 CHAR 24 24 0 0
address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 41 41 0 0 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
grades_0 1 CHAR 99 99 0 1 grades.0
name 1 CHAR 98 98 0 0
restaurant_id 1 CHAR 8 8 0 0
DROP TABLE t1;
#
# Explicit columns
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=2';
SELECT * FROM t1 LIMIT 10;
_id name cuisine borough restaurant_id
58ada47de5a51ddfcd5ed51c Morris Park Bake Shop Bakery Bronx 30075445
58ada47de5a51ddfcd5ed51d Wendy'S Hamburgers Brooklyn 30112340
58ada47de5a51ddfcd5ed51e Dj Reynolds Pub And Restaurant Irish Manhattan 30191841
58ada47de5a51ddfcd5ed51f Riviera Caterer American Brooklyn 40356018
58ada47de5a51ddfcd5ed520 Tov Kosher Kitchen Jewish/Kosher Queens 40356068
58ada47de5a51ddfcd5ed521 Brunos On The Boulevard American Queens 40356151
58ada47de5a51ddfcd5ed522 Kosher Island Jewish/Kosher Staten Island 40356442
58ada47de5a51ddfcd5ed523 Wilken'S Fine Food Delicatessen Brooklyn 40356483
58ada47de5a51ddfcd5ed524 Regina Caterers American Brooklyn 40356649
58ada47de5a51ddfcd5ed525 Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn 40356731
DROP TABLE t1;
#
# Test discovery
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Level=1,Driver=Java,Version=2' DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` char(41) NOT NULL `FIELD_FORMAT`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
`grades_0` char(99) DEFAULT NULL `FIELD_FORMAT`='grades.0',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=2' `DATA_CHARSET`='utf8'
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 [ -73.856077 , 40.848447] Morris Park Ave 10462 Bronx Bakery { "date" : { "$date" : "2014-03-03T00:00:00.000Z"} , "grade" : "A" , "score" : 2} Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 [ -73.961704 , 40.662942] Flatbush Avenue 11225 Brooklyn Hamburgers { "date" : { "$date" : "2014-12-30T00:00:00.000Z"} , "grade" : "A" , "score" : 8} Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 [ -73.98513559999999 , 40.7676919] West 57 Street 10019 Manhattan Irish { "date" : { "$date" : "2014-09-06T00:00:00.000Z"} , "grade" : "A" , "score" : 2} Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 [ -73.98241999999999 , 40.579505] Stillwell Avenue 11224 Brooklyn American { "date" : { "$date" : "2014-06-10T00:00:00.000Z"} , "grade" : "A" , "score" : 5} Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 [ -73.8601152 , 40.7311739] 63 Road 11374 Queens Jewish/Kosher { "date" : { "$date" : "2014-11-24T00:00:00.000Z"} , "grade" : "Z" , "score" : 20} Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET=utf8
COLIST='{"grades":0}' OPTION_LIST='Driver=Java,Version=2,level=0' ;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
58ada47de5a51ddfcd5ed51c { "building" : "1007" , "coord" : [ -73.856077 , 40.848447] , "street" : "Morris Park Ave" , "zipcode" : "10462"} Bronx Bakery Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d { "building" : "469" , "coord" : [ -73.961704 , 40.662942] , "street" : "Flatbush Avenue" , "zipcode" : "11225"} Brooklyn Hamburgers Wendy'S 30112340
58ada47de5a51ddfcd5ed51e { "building" : "351" , "coord" : [ -73.98513559999999 , 40.7676919] , "street" : "West 57 Street" , "zipcode" : "10019"} Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f { "building" : "2780" , "coord" : [ -73.98241999999999 , 40.579505] , "street" : "Stillwell Avenue" , "zipcode" : "11224"} Brooklyn American Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 { "building" : "97-22" , "coord" : [ -73.8601152 , 40.7311739] , "street" : "63 Road" , "zipcode" : "11374"} Queens Jewish/Kosher Tov Kosher Kitchen 40356068
58ada47de5a51ddfcd5ed521 { "building" : "8825" , "coord" : [ -73.8803827 , 40.7643124] , "street" : "Astoria Boulevard" , "zipcode" : "11369"} Queens American Brunos On The Boulevard 40356151
58ada47de5a51ddfcd5ed522 { "building" : "2206" , "coord" : [ -74.1377286 , 40.6119572] , "street" : "Victory Boulevard" , "zipcode" : "10314"} Staten Island Jewish/Kosher Kosher Island 40356442
58ada47de5a51ddfcd5ed523 { "building" : "7114" , "coord" : [ -73.9068506 , 40.6199034] , "street" : "Avenue U" , "zipcode" : "11234"} Brooklyn Delicatessen Wilken'S Fine Food 40356483
58ada47de5a51ddfcd5ed524 { "building" : "6409" , "coord" : [ -74.00528899999999 , 40.628886] , "street" : "11 Avenue" , "zipcode" : "11219"} Brooklyn American Regina Caterers 40356649
58ada47de5a51ddfcd5ed525 { "building" : "1839" , "coord" : [ -73.9482609 , 40.6408271] , "street" : "Nostrand Avenue" , "zipcode" : "11226"} Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=2' ;
SELECT * FROM t1 LIMIT 1;
_id 58ada47de5a51ddfcd5ed51c
name Morris Park Bake Shop
cuisine Bakery
borough Bronx
street Morris Park Ave
building 1007
zipcode 10462
grade A
score 2
date 2014-03-03
restaurant_id 30075445
SELECT name, street, score, date FROM t1 LIMIT 5;
name street score date
Morris Park Bake Shop Morris Park Ave 2 2014-03-03
Wendy'S Flatbush Avenue 8 2014-12-30
Dj Reynolds Pub And Restaurant West 57 Street 2 2014-09-06
Riviera Caterer Stillwell Avenue 5 2014-06-10
Tov Kosher Kitchen 63 Road 20 2014-11-24
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
name cuisine borough
Morris Park Bake Shop Bakery Bronx
Wendy'S Hamburgers Brooklyn
Dj Reynolds Pub And Restaurant Irish Manhattan
Riviera Caterer American Brooklyn
Kosher Island Jewish/Kosher Staten Island
Wilken'S Fine Food Delicatessen Brooklyn
Regina Caterers American Brooklyn
Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn
Wild Asia American Bronx
C & C Catering Service American Brooklyn
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
COUNT(*)
20687
SELECT * FROM t1 WHERE cuisine = 'English';
_id name cuisine borough street building zipcode grade score date restaurant_id
58ada47de5a51ddfcd5ed83d Tea And Sympathy English Manhattan Greenwich Avenue 108 10011 A 8 2014-10-23 40391531
58ada47de5a51ddfcd5ed85c Tartine English Manhattan West 11 Street 253 10014 A 11 2014-08-14 40392496
58ada47de5a51ddfcd5ee1f3 The Park Slope Chipshop English Brooklyn 5 Avenue 383 11215 B 17 2014-09-29 40816202
58ada47de5a51ddfcd5ee7e4 Pound And Pence English Manhattan Liberty Street 55 10005 A 7 2014-02-11 41022701
58ada47de5a51ddfcd5ee999 Chip Shop English Brooklyn Atlantic Avenue 129 11201 A 9 2014-10-08 41076583
58ada47ee5a51ddfcd5efe3f The Breslin Bar & Dining Room English Manhattan West 29 Street 16 10001 A 13 2014-06-09 41443706
58ada47ee5a51ddfcd5efe99 Highlands Restaurant English Manhattan West 10 Street 150 10014 A 12 2014-10-22 41448559
58ada47ee5a51ddfcd5f0413 The Fat Radish English Manhattan Orchard Street 17 10002 A 12 2014-07-26 41513545
58ada47ee5a51ddfcd5f0777 Jones Wood Foundry English Manhattan East 76 Street 401 10021 A 12 2014-12-03 41557377
58ada47ee5a51ddfcd5f0ea2 Whitehall English Manhattan Greenwich Avenue 19 10014 Z 15 2015-01-16 41625263
58ada47ee5a51ddfcd5f1004 The Churchill Tavern English Manhattan East 28 Street 45 10016 A 13 2014-08-27 41633327
58ada47ee5a51ddfcd5f13d5 The Monro English Brooklyn 5 Avenue 481 11215 A 7 2014-06-03 41660253
58ada47ee5a51ddfcd5f1454 The Cock & Bull English Manhattan West 45 Street 23 10036 A 7 2014-08-07 41664704
58ada47ee5a51ddfcd5f176e Dear Bushwick English Brooklyn Wilson Avenue 41 11237 A 12 2014-12-27 41690534
58ada47ee5a51ddfcd5f1e91 Snowdonia Pub English Queens 32 Street 34-55 11106 A 12 2014-10-28 50000290
58ada47ee5a51ddfcd5f2ddc Oscar'S Place English Manhattan Hudson Street 466 10014 A 10 2014-08-18 50011097
SELECT * FROM t1 WHERE score = building;
_id name cuisine borough street building zipcode grade score date restaurant_id
DROP TABLE t1;
#
# Specifying Filter
#
CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
OPTION_LIST='Driver=Java,Version=2' ;
SELECT name FROM t1 WHERE borough = 'Queens';
name
La Baraka Restaurant
Air France Lounge
Tournesol
Winegasm
Cafe Henri
Bistro 33
Domaine Wine Bar
Cafe Triskell
Cannelle Patisserie
La Vie
Dirty Pierres Bistro
Fresca La Crepe
Bliss 46 Bistro
Bear
Cuisine By Claudette
Paris Baguette
The Baroness Bar
Francis Cafe
Madame Sou Sou
Crepe 'N' Tearia
Aperitif Bayside Llc
DROP TABLE t1;
#
# Testing pipeline
#
CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
OPTION_LIST='Driver=Java,Version=2,Pipeline=1' ;
SELECT * FROM t1 LIMIT 10;
name borough date grade score
Tout Va Bien Manhattan 2014-11-10 01:00:00 B 15
Tout Va Bien Manhattan 2014-04-03 02:00:00 A 13
Tout Va Bien Manhattan 2013-07-17 02:00:00 C 36
Tout Va Bien Manhattan 2013-02-06 01:00:00 B 22
Tout Va Bien Manhattan 2012-07-16 02:00:00 C 36
Tout Va Bien Manhattan 2012-03-08 01:00:00 C 7
La Grenouille Manhattan 2014-04-09 02:00:00 A 10
La Grenouille Manhattan 2013-03-05 01:00:00 A 9
La Grenouille Manhattan 2012-02-02 01:00:00 A 13
Le Perigord Manhattan 2014-07-14 02:00:00 B 14
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
name grade score date
Bistro Sk A 10 2014-11-21 01:00:00
Bistro Sk A 12 2014-02-19 01:00:00
Bistro Sk B 18 2013-06-12 02:00:00
DROP TABLE t1;
#
# try level 2 discovery
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
COLIST='{"cuisine":0}'
OPTION_LIST='Driver=Java,level=2,version=2';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
`address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0',
`address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date',
`grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=2'
SELECT name, borough, address_street, grades_0_score AS score FROM t1 WHERE grades_0_grade = 'B';
name borough address_street score
Le Gamin Brooklyn Vanderbilt Avenue 24
Bistro 33 Queens Ditmars Boulevard 15
Dirty Pierres Bistro Queens Station Square 22
Santos Anne Brooklyn Union Avenue 26
Le Paddock Brooklyn Prospect Avenue 17
La Crepe Et La Vie Brooklyn Foster Avenue 24
Francis Cafe Queens Ditmars Boulevard 19
DROP TABLE t1;
#
# try CRUD operations
#
false
CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll'
OPTION_LIST='Driver=Java,Version=2' ;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
_id msg
0 NULL
1 One
2 Two
3 Three
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
_id msg
1 One
2 Deux
3 Three
DELETE FROM t1;
DROP TABLE t1;
true
#
# List states whose population is equal or more than 10 millions
#
false
CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=Java,Version=2' DATA_CHARSET='utf8';
# Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
state totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
# Using a pipeline for grouping
CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$group":{"_id":"$state","totalPop":{"$sum":"$pop"}}},{"$match":{"totalPop":{"$gte":10000000}}},{"$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=Java,Version=2,Pipeline=1' ;
SELECT * FROM t1;
_id totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
true
#
# Test making array
#
CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=2' ;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
_id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
# Test array aggregation
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll'
COLIST='{"pipeline":[{"$project":{"_id":0,"item":1,"total":{"$sum":"$prices"},"average":{"$avg":"$prices"}}}]}'
OPTION_LIST='Driver=Java,Version=2,Pipeline=YES' ;
SELECT * FROM t1;
item total average
journal 285 57.00
notebook 1368 456.00
paper 23 5.75
planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true

View File

@@ -0,0 +1,379 @@
SET GLOBAL connect_class_path='C:/MariaDB-10.2/MariaDB/storage/connect/mysql-test/connect/std_data/Mongo3.jar';
#
# Test the MONGO table type
#
CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Driver=Java,Version=3' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
Document
{ "_id" : { "$oid" : "58ada47de5a51ddfcd5ed51c" }, "address" : { "building" : "1007", "coord" : [-73.856077, 40.848447], "street" : "Morris Park Ave", "zipcode" : "10462" }, "borough" : "Bronx", "cuisine" : "Bakery", "grades" : [{ "date" : { "$date" : 1393804800000 }, "grade" : "A", "score" : 2 }, { "date" : { "$date" : 1378857600000 }, "grade" : "A", "score" : 6 }, { "date" : { "$date" : 1358985600000 }, "grade" : "A", "score" : 10 }, { "date" : { "$date" : 1322006400000 }, "grade" : "A", "score" : 9 }, { "date" : { "$date" : 1299715200000 }, "grade" : "B", "score" : 14 }], "name" : "Morris Park Bake Shop", "restaurant_id" : "30075445" }
{ "_id" : { "$oid" : "58ada47de5a51ddfcd5ed51d" }, "address" : { "building" : "469", "coord" : [-73.961704, 40.662942], "street" : "Flatbush Avenue", "zipcode" : "11225" }, "borough" : "Brooklyn", "cuisine" : "Hamburgers", "grades" : [{ "date" : { "$date" : 1419897600000 }, "grade" : "A", "score" : 8 }, { "date" : { "$date" : 1404172800000 }, "grade" : "B", "score" : 23 }, { "date" : { "$date" : 1367280000000 }, "grade" : "A", "score" : 12 }, { "date" : { "$date" : 1336435200000 }, "grade" : "A", "score" : 12 }], "name" : "Wendy'S", "restaurant_id" : "30112340" }
{ "_id" : { "$oid" : "58ada47de5a51ddfcd5ed51e" }, "address" : { "building" : "351", "coord" : [-73.98513559999999, 40.7676919], "street" : "West 57 Street", "zipcode" : "10019" }, "borough" : "Manhattan", "cuisine" : "Irish", "grades" : [{ "date" : { "$date" : 1409961600000 }, "grade" : "A", "score" : 2 }, { "date" : { "$date" : 1374451200000 }, "grade" : "A", "score" : 11 }, { "date" : { "$date" : 1343692800000 }, "grade" : "A", "score" : 12 }, { "date" : { "$date" : 1325116800000 }, "grade" : "A", "score" : 12 }], "name" : "Dj Reynolds Pub And Restaurant", "restaurant_id" : "30191841" }
DROP TABLE t1;
#
# Test catfunc
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=Java,Version=3' DATA_CHARSET=utf8 ;
SELECT * from t1;
Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Nullable Bpath
_id 1 CHAR 24 24 0 0
address_building 1 CHAR 10 10 0 0 address.building
address_coord 1 CHAR 39 39 0 0 address.coord
address_street 1 CHAR 38 38 0 0 address.street
address_zipcode 1 CHAR 5 5 0 0 address.zipcode
borough 1 CHAR 13 13 0 0
cuisine 1 CHAR 64 64 0 0
grades_0 1 CHAR 84 84 0 1 grades.0
name 1 CHAR 98 98 0 0
restaurant_id 1 CHAR 8 8 0 0
DROP TABLE t1;
#
# Explicit columns
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=3';
SELECT * FROM t1 LIMIT 10;
_id name cuisine borough restaurant_id
58ada47de5a51ddfcd5ed51c Morris Park Bake Shop Bakery Bronx 30075445
58ada47de5a51ddfcd5ed51d Wendy'S Hamburgers Brooklyn 30112340
58ada47de5a51ddfcd5ed51e Dj Reynolds Pub And Restaurant Irish Manhattan 30191841
58ada47de5a51ddfcd5ed51f Riviera Caterer American Brooklyn 40356018
58ada47de5a51ddfcd5ed520 Tov Kosher Kitchen Jewish/Kosher Queens 40356068
58ada47de5a51ddfcd5ed521 Brunos On The Boulevard American Queens 40356151
58ada47de5a51ddfcd5ed522 Kosher Island Jewish/Kosher Staten Island 40356442
58ada47de5a51ddfcd5ed523 Wilken'S Fine Food Delicatessen Brooklyn 40356483
58ada47de5a51ddfcd5ed524 Regina Caterers American Brooklyn 40356649
58ada47de5a51ddfcd5ed525 Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn 40356731
DROP TABLE t1;
#
# Test discovery
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
OPTION_LIST='Level=1,Driver=Java,Version=3' DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
`address_building` char(10) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord` char(39) NOT NULL `FIELD_FORMAT`='address.coord',
`address_street` char(38) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`cuisine` char(64) NOT NULL,
`grades_0` char(84) DEFAULT NULL `FIELD_FORMAT`='grades.0',
`name` char(98) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `OPTION_LIST`='Level=1,Driver=Java,Version=3' `DATA_CHARSET`='utf8'
SELECT * FROM t1 LIMIT 5;
_id address_building address_coord address_street address_zipcode borough cuisine grades_0 name restaurant_id
58ada47de5a51ddfcd5ed51c 1007 [-73.856077, 40.848447] Morris Park Ave 10462 Bronx Bakery { "date" : { "$date" : 1393804800000 }, "grade" : "A", "score" : 2 } Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d 469 [-73.961704, 40.662942] Flatbush Avenue 11225 Brooklyn Hamburgers { "date" : { "$date" : 1419897600000 }, "grade" : "A", "score" : 8 } Wendy'S 30112340
58ada47de5a51ddfcd5ed51e 351 [-73.98513559999999, 40.7676919] West 57 Street 10019 Manhattan Irish { "date" : { "$date" : 1409961600000 }, "grade" : "A", "score" : 2 } Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f 2780 [-73.98241999999999, 40.579505] Stillwell Avenue 11224 Brooklyn American { "date" : { "$date" : 1402358400000 }, "grade" : "A", "score" : 5 } Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 97-22 [-73.8601152, 40.7311739] 63 Road 11374 Queens Jewish/Kosher { "date" : { "$date" : 1416787200000 }, "grade" : "Z", "score" : 20 } Tov Kosher Kitchen 40356068
DROP TABLE t1;
#
# Dropping a column
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET=utf8
COLIST='{"grades":0}' OPTION_LIST='Driver=Java,Version=3,level=0' ;
SELECT * FROM t1 LIMIT 10;
_id address borough cuisine name restaurant_id
58ada47de5a51ddfcd5ed51c { "building" : "1007", "coord" : [-73.856077, 40.848447], "street" : "Morris Park Ave", "zipcode" : "10462" } Bronx Bakery Morris Park Bake Shop 30075445
58ada47de5a51ddfcd5ed51d { "building" : "469", "coord" : [-73.961704, 40.662942], "street" : "Flatbush Avenue", "zipcode" : "11225" } Brooklyn Hamburgers Wendy'S 30112340
58ada47de5a51ddfcd5ed51e { "building" : "351", "coord" : [-73.98513559999999, 40.7676919], "street" : "West 57 Street", "zipcode" : "10019" } Manhattan Irish Dj Reynolds Pub And Restaurant 30191841
58ada47de5a51ddfcd5ed51f { "building" : "2780", "coord" : [-73.98241999999999, 40.579505], "street" : "Stillwell Avenue", "zipcode" : "11224" } Brooklyn American Riviera Caterer 40356018
58ada47de5a51ddfcd5ed520 { "building" : "97-22", "coord" : [-73.8601152, 40.7311739], "street" : "63 Road", "zipcode" : "11374" } Queens Jewish/Kosher Tov Kosher Kitchen 40356068
58ada47de5a51ddfcd5ed521 { "building" : "8825", "coord" : [-73.8803827, 40.7643124], "street" : "Astoria Boulevard", "zipcode" : "11369" } Queens American Brunos On The Boulevard 40356151
58ada47de5a51ddfcd5ed522 { "building" : "2206", "coord" : [-74.1377286, 40.6119572], "street" : "Victory Boulevard", "zipcode" : "10314" } Staten Island Jewish/Kosher Kosher Island 40356442
58ada47de5a51ddfcd5ed523 { "building" : "7114", "coord" : [-73.9068506, 40.6199034], "street" : "Avenue U", "zipcode" : "11234" } Brooklyn Delicatessen Wilken'S Fine Food 40356483
58ada47de5a51ddfcd5ed524 { "building" : "6409", "coord" : [-74.00528899999999, 40.628886], "street" : "11 Avenue", "zipcode" : "11219" } Brooklyn American Regina Caterers 40356649
58ada47de5a51ddfcd5ed525 { "building" : "1839", "coord" : [-73.9482609, 40.6408271], "street" : "Nostrand Avenue", "zipcode" : "11226" } Brooklyn Ice Cream, Gelato, Yogurt, Ices Taste The Tropics Ice Cream 40356731
DROP TABLE t1;
#
# Specifying Jpath
#
CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=3' ;
SELECT * FROM t1 LIMIT 1;
_id 58ada47de5a51ddfcd5ed51c
name Morris Park Bake Shop
cuisine Bakery
borough Bronx
street Morris Park Ave
building 1007
zipcode 10462
grade A
score 2
date 2014-03-03
restaurant_id 30075445
SELECT name, street, score, date FROM t1 LIMIT 5;
name street score date
Morris Park Bake Shop Morris Park Ave 2 2014-03-03
Wendy'S Flatbush Avenue 8 2014-12-30
Dj Reynolds Pub And Restaurant West 57 Street 2 2014-09-06
Riviera Caterer Stillwell Avenue 5 2014-06-10
Tov Kosher Kitchen 63 Road 20 2014-11-24
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
name cuisine borough
Morris Park Bake Shop Bakery Bronx
Wendy'S Hamburgers Brooklyn
Dj Reynolds Pub And Restaurant Irish Manhattan
Riviera Caterer American Brooklyn
Kosher Island Jewish/Kosher Staten Island
Wilken'S Fine Food Delicatessen Brooklyn
Regina Caterers American Brooklyn
Taste The Tropics Ice Cream Ice Cream, Gelato, Yogurt, Ices Brooklyn
Wild Asia American Bronx
C & C Catering Service American Brooklyn
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
COUNT(*)
20687
SELECT * FROM t1 WHERE cuisine = 'English';
_id name cuisine borough street building zipcode grade score date restaurant_id
58ada47de5a51ddfcd5ed83d Tea And Sympathy English Manhattan Greenwich Avenue 108 10011 A 8 2014-10-23 40391531
58ada47de5a51ddfcd5ed85c Tartine English Manhattan West 11 Street 253 10014 A 11 2014-08-14 40392496
58ada47de5a51ddfcd5ee1f3 The Park Slope Chipshop English Brooklyn 5 Avenue 383 11215 B 17 2014-09-29 40816202
58ada47de5a51ddfcd5ee7e4 Pound And Pence English Manhattan Liberty Street 55 10005 A 7 2014-02-11 41022701
58ada47de5a51ddfcd5ee999 Chip Shop English Brooklyn Atlantic Avenue 129 11201 A 9 2014-10-08 41076583
58ada47ee5a51ddfcd5efe3f The Breslin Bar & Dining Room English Manhattan West 29 Street 16 10001 A 13 2014-06-09 41443706
58ada47ee5a51ddfcd5efe99 Highlands Restaurant English Manhattan West 10 Street 150 10014 A 12 2014-10-22 41448559
58ada47ee5a51ddfcd5f0413 The Fat Radish English Manhattan Orchard Street 17 10002 A 12 2014-07-26 41513545
58ada47ee5a51ddfcd5f0777 Jones Wood Foundry English Manhattan East 76 Street 401 10021 A 12 2014-12-03 41557377
58ada47ee5a51ddfcd5f0ea2 Whitehall English Manhattan Greenwich Avenue 19 10014 Z 15 2015-01-16 41625263
58ada47ee5a51ddfcd5f1004 The Churchill Tavern English Manhattan East 28 Street 45 10016 A 13 2014-08-27 41633327
58ada47ee5a51ddfcd5f13d5 The Monro English Brooklyn 5 Avenue 481 11215 A 7 2014-06-03 41660253
58ada47ee5a51ddfcd5f1454 The Cock & Bull English Manhattan West 45 Street 23 10036 A 7 2014-08-07 41664704
58ada47ee5a51ddfcd5f176e Dear Bushwick English Brooklyn Wilson Avenue 41 11237 A 12 2014-12-27 41690534
58ada47ee5a51ddfcd5f1e91 Snowdonia Pub English Queens 32 Street 34-55 11106 A 12 2014-10-28 50000290
58ada47ee5a51ddfcd5f2ddc Oscar'S Place English Manhattan Hudson Street 466 10014 A 10 2014-08-18 50011097
SELECT * FROM t1 WHERE score = building;
_id name cuisine borough street building zipcode grade score date restaurant_id
DROP TABLE t1;
#
# Specifying Filter
#
CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
OPTION_LIST='Driver=Java,Version=3' ;
SELECT name FROM t1 WHERE borough = 'Queens';
name
La Baraka Restaurant
Air France Lounge
Tournesol
Winegasm
Cafe Henri
Bistro 33
Domaine Wine Bar
Cafe Triskell
Cannelle Patisserie
La Vie
Dirty Pierres Bistro
Fresca La Crepe
Bliss 46 Bistro
Bear
Cuisine By Claudette
Paris Baguette
The Baroness Bar
Francis Cafe
Madame Sou Sou
Crepe 'N' Tearia
Aperitif Bayside Llc
DROP TABLE t1;
#
# Testing pipeline
#
CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
OPTION_LIST='Driver=Java,Version=3,Pipeline=1' ;
SELECT * FROM t1 LIMIT 10;
name borough date grade score
Tout Va Bien Manhattan 2014-11-10 01:00:00 B 15
Tout Va Bien Manhattan 2014-04-03 02:00:00 A 13
Tout Va Bien Manhattan 2013-07-17 02:00:00 C 36
Tout Va Bien Manhattan 2013-02-06 01:00:00 B 22
Tout Va Bien Manhattan 2012-07-16 02:00:00 C 36
Tout Va Bien Manhattan 2012-03-08 01:00:00 C 7
La Grenouille Manhattan 2014-04-09 02:00:00 A 10
La Grenouille Manhattan 2013-03-05 01:00:00 A 9
La Grenouille Manhattan 2012-02-02 01:00:00 A 13
Le Perigord Manhattan 2014-07-14 02:00:00 B 14
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
name grade score date
Bistro Sk A 10 2014-11-21 01:00:00
Bistro Sk A 12 2014-02-19 01:00:00
Bistro Sk B 18 2013-06-12 02:00:00
DROP TABLE t1;
#
# try level 2 discovery
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"$ne":"Manhattan"}}'
COLIST='{"cuisine":0}'
OPTION_LIST='Driver=Java,level=2,version=3';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`_id` char(24) NOT NULL,
`address_building` char(6) NOT NULL `FIELD_FORMAT`='address.building',
`address_coord_0` double(18,14) NOT NULL `FIELD_FORMAT`='address.coord.0',
`address_street` char(25) NOT NULL `FIELD_FORMAT`='address.street',
`address_zipcode` char(5) NOT NULL `FIELD_FORMAT`='address.zipcode',
`borough` char(13) NOT NULL,
`grades_0_date` datetime NOT NULL `FIELD_FORMAT`='grades.0.date',
`grades_0_grade` char(14) NOT NULL `FIELD_FORMAT`='grades.0.grade',
`grades_0_score` int(2) NOT NULL `FIELD_FORMAT`='grades.0.score',
`name` char(32) NOT NULL,
`restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `COLIST`='{"cuisine":0}' `FILTER`='{"cuisine":"French","borough":{"$ne":"Manhattan"}}' `OPTION_LIST`='Driver=Java,level=2,version=3'
SELECT name, borough, address_street, grades_0_score AS score FROM t1 WHERE grades_0_grade = 'B';
name borough address_street score
Le Gamin Brooklyn Vanderbilt Avenue 24
Bistro 33 Queens Ditmars Boulevard 15
Dirty Pierres Bistro Queens Station Square 22
Santos Anne Brooklyn Union Avenue 26
Le Paddock Brooklyn Prospect Avenue 17
La Crepe Et La Vie Brooklyn Foster Avenue 24
Francis Cafe Queens Ditmars Boulevard 19
DROP TABLE t1;
#
# try CRUD operations
#
false
CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll'
OPTION_LIST='Driver=Java,Version=3' ;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
_id msg
0 NULL
1 One
2 Two
3 Three
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
_id msg
1 One
2 Deux
3 Three
DELETE FROM t1;
DROP TABLE t1;
true
#
# List states whose population is equal or more than 10 millions
#
false
CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=Java,Version=3' DATA_CHARSET='utf8';
# Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
state totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
# Using a pipeline for grouping
CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"$group":{"_id":"$state","totalPop":{"$sum":"$pop"}}},{"$match":{"totalPop":{"$gte":10000000}}},{"$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=Java,Version=3,Pipeline=1' ;
SELECT * FROM t1;
_id totalPop
CA 29754890
NY 17990402
TX 16984601
FL 12686644
PA 11881643
IL 11427576
OH 10846517
DROP TABLE t1;
true
#
# Test making array
#
CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=Java,Version=3' ;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
_id item prices_0 prices_1 prices_2 prices_3 prices_4
1 journal 87 45 63 12 78
2 notebook 123 456 789 NULL NULL
3 paper 5 7 3 8 NULL
4 planner 25 71 NULL 44 27
5 postcard 5 7 3 8 NULL
DROP TABLE t1;
#
# Test array aggregation
#
CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=MONGO TABNAME='testcoll'
COLIST='{"pipeline":[{"$project":{"_id":0,"item":1,"total":{"$sum":"$prices"},"average":{"$avg":"$prices"}}}]}'
OPTION_LIST='Driver=Java,Version=3,Pipeline=YES' ;
SELECT * FROM t1;
item total average
journal 285 57.00
notebook 1368 456.00
paper 23 5.75
planner 167 41.75
postcard 23 5.75
DROP TABLE t1;
true

View File

@@ -1,5 +1,10 @@
connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
connection master;
CREATE DATABASE connect;
connection slave;
CREATE DATABASE connect;
connection slave;
CREATE TABLE t1 (
`id` int(20) primary key,
`group` int NOT NULL default 1,
@@ -7,14 +12,15 @@ CREATE TABLE t1 (
`a\\` int unsigned,
`name` varchar(32) default 'name')
DEFAULT CHARSET=latin1;
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(20) NOT NULL,
`group` int(11) NOT NULL DEFAULT '1',
`a\\b` int(11) NOT NULL DEFAULT '2',
`group` int(11) NOT NULL DEFAULT 1,
`a\\b` int(11) NOT NULL DEFAULT 2,
`a\\` int(10) unsigned DEFAULT NULL,
`name` varchar(32) DEFAULT 'name'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' `TABLE_TYPE`='MYSQL'
@@ -25,12 +31,15 @@ id group a\\b a\\ name
1 1 2 NULL foo
2 1 2 NULL fee
DROP TABLE t1;
connection slave;
SELECT * FROM t1;
id group a\\b a\\ name
1 1 2 NULL foo
2 1 2 NULL fee
DROP TABLE t1;
connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;

View File

@@ -1,8 +1,13 @@
connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
connection master;
CREATE DATABASE connect;
connection slave;
CREATE DATABASE connect;
#
# Checking Sending Commands
#
connection master;
CREATE TABLE t1 (
command VARCHAR(128) NOT NULL,
warnings INT(4) NOT NULL FLAG=3,
@@ -15,7 +20,7 @@ SELECT * FROM t1 WHERE command IN ('Warning','Note',
"insert into t1(msg) values('One'),(NULL),('Three')",
"insert into t1 values(2,'Deux') on duplicate key update msg = 'Two'",
"insert into t1(message) values('Four'),('Five'),('Six')",
'insert into t1(id) values(NULL)',
'insert ignore into t1(id) values(NULL)',
"update t1 set msg = 'Four' where id = 4",
'select * from t1');
command warnings number message
@@ -26,7 +31,7 @@ insert into t1(msg) values('One'),(NULL),('Three') 1 3 Affected rows
Warning 0 1048 Column 'msg' cannot be null
insert into t1 values(2,'Deux') on duplicate key update msg = 'Two' 0 2 Affected rows
insert into t1(message) values('Four'),('Five'),('Six') 0 1054 Remote: Unknown column 'message' in 'field list'
insert into t1(id) values(NULL) 1 1 Affected rows
insert ignore into t1(id) values(NULL) 1 1 Affected rows
Warning 0 1364 Field 'msg' doesn't have a default value
update t1 set msg = 'Four' where id = 4 0 1 Affected rows
select * from t1 0 2 Result set columns
@@ -39,15 +44,16 @@ Note 1305 PROCEDURE test.p1 does not exist
CREATE PROCEDURE p1(cmd varchar(512))
READS SQL DATA
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
CALL p1('insert into t1(id) values(NULL)');
CALL p1('insert ignore into t1(id) values(NULL)');
command warnings number message
insert into t1(id) values(NULL) 1 1 Affected rows
insert ignore into t1(id) values(NULL) 1 1 Affected rows
Warning 0 1364 Field 'msg' doesn't have a default value
CALL p1('update t1 set msg = "Five" where id = 5');
command warnings number message
update t1 set msg = "Five" where id = 5 0 1 Affected rows
DROP PROCEDURE p1;
DROP TABLE t1;
connection slave;
SELECT * FROM t1;
id msg
1 One
@@ -56,7 +62,9 @@ id msg
4 Four
5 Five
DROP TABLE t1;
connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;

View File

@@ -5,11 +5,14 @@ set sql_mode="";
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
set sql_mode=default;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=MySQL OPTION_LIST='host=localhost,user=root1,port=PORT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
@@ -21,6 +24,7 @@ a
10
20
30
connection user;
SELECT user();
user()
user@localhost
@@ -39,10 +43,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -54,6 +60,8 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
disconnect user;
connection default;
SELECT user();
user()
root@localhost

View File

@@ -1,5 +1,10 @@
connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
connection master;
CREATE DATABASE connect;
connection slave;
CREATE DATABASE connect;
connection slave;
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
SELECT * FROM t1;
@@ -12,6 +17,7 @@ NULL NULL
#
# Testing errors
#
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://unknown@127.0.0.1:SLAVE_PORT/test/t1';
ERROR HY000: (1045) Access denied for user 'unknown'@'localhost' (using password: NO)
@@ -39,10 +45,14 @@ ERROR HY000: Got error 174 '(1054) Unknown column 'x' in 'field list' [SELECT `x
DROP TABLE t1;
CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1';
connection slave;
ALTER TABLE t1 RENAME t1backup;
connection master;
SELECT * FROM t1;
ERROR HY000: Got error 174 '(1146) Table 'test.t1' doesn't exist [SELECT `a`, `b` FROM `t1`]' from CONNECT
connection slave;
ALTER TABLE t1backup RENAME t1;
connection master;
DROP TABLE t1;
#
# Testing SELECT, etc.
@@ -111,6 +121,7 @@ NULL NULL
2 0
3 0
DROP TABLE t1;
connection slave;
DROP TABLE t1;
#
# Testing numeric data types
@@ -129,6 +140,7 @@ t1 CREATE TABLE `t1` (
`h` decimal(20,5) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265);
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
OPTION_LIST='host=127.0.0.1,user=root,port=SLAVE_PORT';
SHOW CREATE TABLE t1;
@@ -147,6 +159,7 @@ SELECT * FROM t1;
a b c d e f g h
100 3333 41235 1234567890 235000000000 3.14159 3.14159265 3141.59265
DROP TABLE t1;
connection slave;
DROP TABLE t1;
#
# Testing character data types
@@ -162,6 +175,7 @@ INSERT INTO t1 VALUES('Welcome','Hello, World');
SELECT * FROM t1;
a b
Welcome Hello, World
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
SHOW CREATE TABLE t1;
@@ -174,6 +188,7 @@ SELECT * FROM t1;
a b
Welcome Hello, World
DROP TABLE t1;
connection slave;
DROP TABLE t1;
#
# Testing temporal data types
@@ -185,10 +200,10 @@ t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`e` year(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
INSERT IGNORE INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
Warnings:
Note 1265 Data truncated for column 'a' at row 1
Note 1265 Data truncated for column 'c' at row 1
@@ -196,6 +211,7 @@ Warning 1265 Data truncated for column 'e' at row 1
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
connection master;
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT';
SHOW CREATE TABLE t1;
@@ -204,15 +220,18 @@ t1 CREATE TABLE `t1` (
`a` date DEFAULT NULL,
`b` datetime DEFAULT NULL,
`c` time DEFAULT NULL,
`d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`d` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`e` year(4) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT' `TABLE_TYPE`='MYSQL'
SELECT * FROM t1;
a b c d e
2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003
DROP TABLE t1;
connection slave;
DROP TABLE t1;
connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;

View File

@@ -141,22 +141,3 @@ DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
#
# Checking thread TBL tables
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
v
11
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v';
SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
SELECT * FROM total order by v desc;
v
22
11
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;

View File

@@ -0,0 +1,118 @@
connect master,127.0.0.1,root,,test,$MASTER_MYPORT,;
connect slave,127.0.0.1,root,,test,$SLAVE_MYPORT,;
connection master;
CREATE DATABASE connect;
connection slave;
CREATE DATABASE connect;
connection default;
#
# Checking thread TBL tables
#
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
SELECT * FROM t1;
a b
0 test00
1 test01
2 test02
3 test03
connection master;
CREATE TABLE rt2 (a int, b char(10));
INSERT INTO rt2 VALUES (4,'test04'),(5,'test05'),(6,'test06'),(7,'test07');
SELECT * FROM rt2;
a b
4 test04
5 test05
6 test06
7 test07
connection slave;
CREATE TABLE rt3 (a int, b char(10));
INSERT INTO rt3 VALUES (8,'test08'),(9,'test09'),(10,'test10'),(11,'test11');
SELECT * FROM rt3;
a b
8 test08
9 test09
10 test10
11 test11
connection default;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@localhost:MASTER_PORT/test/rt2';
SELECT * FROM t2;
a b
4 test04
5 test05
6 test06
7 test07
CREATE TABLE t3 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@localhost:SLAVE_PORT/test/rt3';
SELECT * FROM t3;
a b
8 test08
9 test09
10 test10
11 test11
CREATE TABLE total (a int, b char(10))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3'
OPTION_LIST='thread=yes,port=PORT';
SELECT * FROM total order by a desc;
a b
11 test11
10 test10
9 test09
8 test08
7 test07
6 test06
5 test05
4 test04
3 test03
2 test02
1 test01
0 test00
connection master;
DROP TABLE rt2;
connection slave;
DROP TABLE rt3;
connection default;
DROP TABLE t1,t2,t3,total;
#
# Old thread TBL tables test modified
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v' OPTION_LIST='port=MASTER_PORT';
SELECT * FROM t1;
v
11
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v' OPTION_LIST='port=SLAVE_PORT';
SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
SELECT * FROM total order by v desc;
v
22
11
DROP TABLE t1,t2,total;
#
# Old thread TBL tables test not modified
#
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
v
11
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v';
SELECT * FROM t2;
v
22
CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=PORT';;
SELECT * FROM total order by v desc;
v
22
11
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;
connection master;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;
connection slave;
DROP TABLE IF EXISTS connect.t1;
DROP DATABASE IF EXISTS connect;

View File

@@ -27,13 +27,13 @@ UPDATE t1 SET e = d;
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
UPDATE t1 SET c = d;
UPDATE IGNORE t1 SET c = d;
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
SELECT * FROM t1;
a b c d e
255 65535 4294967295 18446744073709551615 18446744073709551615
UPDATE t1 SET c = e;
UPDATE IGNORE t1 SET c = e;
Warnings:
Warning 1264 Out of range value for column 'c' at row 1
SELECT * FROM t1;

View File

@@ -1,3 +1,4 @@
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
CREATE TABLE employee
(
serialno CHAR(5) NOT NULL,
@@ -1625,3 +1626,4 @@ serialno name sex title manager department secretary salary
#
DROP PROCEDURE test.tst_up;
DROP TABLE employee;
SET sql_mode = DEFAULT;

View File

@@ -1,5 +1,3 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing tag values
@@ -12,7 +10,7 @@ TRANSLATOR CHAR(40),
PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT * FROM t1;
AUTHOR Jean-Christophe Bernadac
TITLE Construire une application XML
@@ -36,7 +34,7 @@ TRANSLATOR CHAR(40),
PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT * FROM t1;
author NULL
TITLE Construire une application XML
@@ -57,7 +55,7 @@ ISBN CHAR(15),
LANG CHAR(2),
SUBJECT CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='Coltype=@,xmlsup=libxml2';
OPTION_LIST='Coltype=@,xmlsup=domdoc';
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
@@ -74,7 +72,7 @@ isbn CHAR(15),
LANG CHAR(2),
SUBJECT CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='Coltype=@,xmlsup=libxml2';
OPTION_LIST='Coltype=@,xmlsup=domdoc';
SELECT * FROM t1;
isbn NULL
LANG fr
@@ -97,7 +95,7 @@ PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK'
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
@@ -130,7 +128,7 @@ PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.xml'
TABNAME='BIBLIO'
OPTION_LIST='rownode=BOOK,xmlsup=libxml2';
OPTION_LIST='rownode=BOOK,xmlsup=domdoc';
INSERT INTO t1 (ISBN, LANG, SUBJECT, AUTHOR, TITLE, PUBLISHEr, DATEPUB)
VALUES('9782212090529','fr','général','Alain Michard',
'XML, Langage et Applications','Eyrolles Paris',1998);
@@ -162,38 +160,38 @@ DATEPUB 1998
SELECT LOAD_FILE('MYSQLD_DATADIR/test/xsample2.xml') AS xml;
xml <?xml version="1.0" encoding="UTF-8"?>
<BIBLIO SUBJECT="XML">
<BOOK ISBN="9782212090819" LANG="fr" SUBJECT="applications">
<AUTHOR>
<FIRSTNAME>Jean-Christophe</FIRSTNAME>
<LASTNAME>Bernadac</LASTNAME>
</AUTHOR>
<AUTHOR>
<FIRSTNAME>François</FIRSTNAME>
<LASTNAME>Knab</LASTNAME>
</AUTHOR>
<TITLE>Construire une application XML</TITLE>
<PUBLISHER>
<NAME>Eyrolles</NAME>
<PLACE>Paris</PLACE>
</PUBLISHER>
<DATEPUB>1999</DATEPUB>
</BOOK>
<BOOK ISBN="9782840825685" LANG="fr" SUBJECT="applications">
<AUTHOR>
<FIRSTNAME>William J.</FIRSTNAME>
<LASTNAME>Pardi</LASTNAME>
</AUTHOR>
<TRANSLATOR PREFIX="adapté de l'anglais par">
<FIRSTNAME>James</FIRSTNAME>
<LASTNAME>Guerin</LASTNAME>
</TRANSLATOR>
<TITLE>XML en Action</TITLE>
<PUBLISHER>
<NAME>Microsoft Press</NAME>
<PLACE>Paris</PLACE>
</PUBLISHER>
<DATEPUB>1999</DATEPUB>
</BOOK>
<BOOK ISBN="9782212090819" LANG="fr" SUBJECT="applications">
<AUTHOR>
<FIRSTNAME>Jean-Christophe</FIRSTNAME>
<LASTNAME>Bernadac</LASTNAME>
</AUTHOR>
<AUTHOR>
<FIRSTNAME>François</FIRSTNAME>
<LASTNAME>Knab</LASTNAME>
</AUTHOR>
<TITLE>Construire une application XML</TITLE>
<PUBLISHER>
<NAME>Eyrolles</NAME>
<PLACE>Paris</PLACE>
</PUBLISHER>
<DATEPUB>1999</DATEPUB>
</BOOK>
<BOOK ISBN="9782840825685" LANG="fr" SUBJECT="applications">
<AUTHOR>
<FIRSTNAME>William J.</FIRSTNAME>
<LASTNAME>Pardi</LASTNAME>
</AUTHOR>
<TRANSLATOR PREFIX="adapté de l'anglais par">
<FIRSTNAME>James</FIRSTNAME>
<LASTNAME>Guerin</LASTNAME>
</TRANSLATOR>
<TITLE>XML en Action</TITLE>
<PUBLISHER>
<NAME>Microsoft Press</NAME>
<PLACE>Paris</PLACE>
</PUBLISHER>
<DATEPUB>1999</DATEPUB>
</BOOK>
<BOOK ISBN="9782212090529" LANG="fr" SUBJECT="général">
<AUTHOR>Alain Michard</AUTHOR>
<TITLE>XML, Langage et Applications</TITLE>
@@ -220,7 +218,7 @@ publisher CHAR(20) FIELD_FORMAT='PUBLISHER/NAME',
location CHAR(20) FIELD_FORMAT='PUBLISHER/PLACE',
year INT(4) FIELD_FORMAT='DATEPUB'
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=libxml2';
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=domdoc';
SELECT * FROM t1;
isbn 9782212090819
language fr
@@ -262,7 +260,7 @@ CREATE TABLE t1
(
isbn CHAR(15) FIELD_FORMAT='@isbn'
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=libxml2';
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=domdoc';
SELECT * FROM t1;
isbn NULL
isbn NULL
@@ -274,20 +272,20 @@ CREATE TABLE t1
(
c CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2'
OPTION_LIST='xmlsup=domdoc'
DATA_CHARSET=latin1;
ERROR HY000: DATA_CHARSET='latin1' is not supported for TABLE_TYPE=XML
CREATE TABLE t1
(
c CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2'
OPTION_LIST='xmlsup=domdoc'
DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table t1
Create Table CREATE TABLE `t1` (
`c` char(16) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=XML `FILE_NAME`='latin1.xml' `OPTION_LIST`='xmlsup=libxml2' `DATA_CHARSET`=utf8
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=XML `FILE_NAME`='latin1.xml' `OPTION_LIST`='xmlsup=domdoc' `DATA_CHARSET`=utf8
SELECT c, HEX(c) FROM t1;
c ÁÂÃÄÅÆÇ
HEX(c) C1C2C3C4C5C6C7
@@ -296,7 +294,7 @@ CREATE TABLE t1
(
c CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT c, HEX(c) FROM t1;
c ÁÂÃÄÅÆÇ
HEX(c) C1C2C3C4C5C6C7
@@ -305,7 +303,7 @@ CREATE TABLE t1
(
c CHAR(16) CHARACTER SET utf8
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT c, HEX(c) FROM t1;
c ÁÂÃÄÅÆÇ
HEX(c) C381C382C383C384C385C386C387
@@ -318,7 +316,7 @@ CREATE TABLE t1
(
c CHAR(16) CHARACTER SET cp1251
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT c, HEX(c) FROM t1;
c ???????
HEX(c) 3F3F3F3F3F3F3F
@@ -333,44 +331,13 @@ DROP TABLE t1;
#
# Testing Cyrillic
#
CREATE TABLE t1
(
c CHAR(16) CHARACTER SET utf8
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='cp1251.xml'
OPTION_LIST='xmlsup=libxml2,rownode=b';
SELECT * FROM t1;
c БВГДЕЖЗ
INSERT INTO t1 VALUES ('ИКЛМН');
SELECT c, HEX(c) FROM t1;
c БВГДЕЖЗ
HEX(c) D091D092D093D094D095D096D097
c ИКЛМН
HEX(c) D098D09AD09BD09CD09D
DROP TABLE t1;
CREATE TABLE t1
(
c CHAR(16) CHARACTER SET cp1251
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='cp1251.xml'
OPTION_LIST='xmlsup=libxml2,rownode=b';
SELECT * FROM t1;
c БВГДЕЖЗ
c ИКЛМН
INSERT INTO t1 VALUES ('ОПРСТ');
SELECT c, HEX(c) FROM t1;
c БВГДЕЖЗ
HEX(c) C1C2C3C4C5C6C7
c ИКЛМН
HEX(c) C8CACBCCCD
c ОПРСТ
HEX(c) CECFD0D1D2
DROP TABLE t1;
#
# Testing that the underlying file is created with a proper Encoding
#
CREATE TABLE t1 (node VARCHAR(50))
CHARACTER SET latin1
ENGINE=connect TABLE_TYPE=xml FILE_NAME='t1.xml'
OPTION_LIST='xmlsup=libxml2,rownode=line,encoding=utf-8';
OPTION_LIST='xmlsup=domdoc,rownode=line,encoding=utf-8';
INSERT INTO t1 VALUES (_latin1 0xC0C1C2C3);
SELECT node, hex(node) FROM t1;
node ÀÁÂÃ
@@ -384,7 +351,7 @@ HEX(EXTRACTVALUE(@a,'/t1/line/node')) C380C381C382C383
CREATE TABLE t1 (node VARCHAR(50))
CHARACTER SET latin1
ENGINE=connect TABLE_TYPE=xml FILE_NAME='t1.xml'
OPTION_LIST='xmlsup=libxml2,rownode=line,encoding=iso-8859-1';
OPTION_LIST='xmlsup=domdoc,rownode=line,encoding=iso-8859-1';
INSERT INTO t1 VALUES (_latin1 0xC0C1C2C3);
SELECT node, hex(node) FROM t1;
node ÀÁÂÃ
@@ -401,15 +368,16 @@ HEX(EXTRACTVALUE(@a,'/t1/line/node')) C0C1C2C3
CREATE TABLE t1 (node VARCHAR(50))
CHARACTER SET utf8
ENGINE=connect TABLE_TYPE=xml FILE_NAME='t1.xml'
OPTION_LIST='xmlsup=libxml2,rownode=line,encoding=iso-8859-1';
OPTION_LIST='xmlsup=domdoc,rownode=line,encoding=iso-8859-1';
INSERT INTO t1 VALUES (_latin1 0xC0C1C2C3);
INSERT INTO t1 VALUES (_cp1251 0xC0C1C2C3);
Warnings:
Level Warning
Code 1105
Message Com error: Unable to save character to 'iso-8859-1' encoding.
INSERT INTO t1 VALUES ('&<>"\'');
SELECT node, hex(node) FROM t1;
node ÀÁÂÃ
hex(node) C380C381C382C383
node АБВГ
hex(node) D090D091D092D093
node &<>"'
hex(node) 263C3E2227
DROP TABLE t1;
@@ -418,12 +386,6 @@ SELECT CAST(@a AS CHAR CHARACTER SET latin1);
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Created by the MariaDB CONNECT Storage Engine-->
<t1>
<line>
<node>ÀÁÂÃ</node>
</line>
<line>
<node>&#1040;&#1041;&#1042;&#1043;</node>
</line>
<line>
<node>&amp;&lt;&gt;"'</node>
</line>

View File

@@ -0,0 +1,431 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing tag values
#
CREATE TABLE t1
(
AUTHOR CHAR(50),
TITLE CHAR(32),
TRANSLATOR CHAR(40),
PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='xmlsup=libxml2';
SELECT * FROM t1;
AUTHOR Jean-Christophe Bernadac
TITLE Construire une application XML
TRANSLATOR NULL
PUBLISHER Eyrolles Paris
DATEPUB 1999
AUTHOR William J. Pardi
TITLE XML en Action
TRANSLATOR James Guerin
PUBLISHER Microsoft Press Paris
DATEPUB 1999
DROP TABLE t1;
#
# Testing that tag names are case sensitive
#
CREATE TABLE t1
(
author CHAR(50),
TITLE CHAR(32),
TRANSLATOR CHAR(40),
PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='xmlsup=libxml2';
SELECT * FROM t1;
author NULL
TITLE Construire une application XML
TRANSLATOR NULL
PUBLISHER Eyrolles Paris
DATEPUB 1999
author NULL
TITLE XML en Action
TRANSLATOR James Guerin
PUBLISHER Microsoft Press Paris
DATEPUB 1999
DROP TABLE t1;
#
# Testing attribute values
#
CREATE TABLE t1 (
ISBN CHAR(15),
LANG CHAR(2),
SUBJECT CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='Coltype=@,xmlsup=libxml2';
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
SUBJECT applications
ISBN 9782840825685
LANG fr
SUBJECT applications
DROP TABLE t1;
#
# Testing that attribute names are case sensitive
#
CREATE TABLE t1 (
isbn CHAR(15),
LANG CHAR(2),
SUBJECT CHAR(32)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
OPTION_LIST='Coltype=@,xmlsup=libxml2';
SELECT * FROM t1;
isbn NULL
LANG fr
SUBJECT applications
isbn NULL
LANG fr
SUBJECT applications
DROP TABLE t1;
#
# Testing mixed tag and attribute values
#
CREATE TABLE t1 (
ISBN CHAR(15) FIELD_FORMAT='@',
LANG CHAR(2) FIELD_FORMAT='@',
SUBJECT CHAR(32) FIELD_FORMAT='@',
AUTHOR CHAR(50),
TITLE CHAR(32),
TRANSLATOR CHAR(40),
PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK'
OPTION_LIST='xmlsup=libxml2';
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
SUBJECT applications
AUTHOR Jean-Christophe Bernadac
TITLE Construire une application XML
TRANSLATOR NULL
PUBLISHER Eyrolles Paris
DATEPUB 1999
ISBN 9782840825685
LANG fr
SUBJECT applications
AUTHOR William J. Pardi
TITLE XML en Action
TRANSLATOR James Guerin
PUBLISHER Microsoft Press Paris
DATEPUB 1999
DROP TABLE t1;
#
# Testing INSERT on mixed tag and attribute values
#
CREATE TABLE t1 (
ISBN CHAR(15) FIELD_FORMAT='@',
LANG CHAR(2) FIELD_FORMAT='@',
SUBJECT CHAR(32) FIELD_FORMAT='@',
AUTHOR CHAR(50),
TITLE CHAR(32),
TRANSLATOR CHAR(40),
PUBLISHER CHAR(40),
DATEPUB INT(4)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.xml'
TABNAME='BIBLIO'
OPTION_LIST='rownode=BOOK,xmlsup=libxml2';
INSERT INTO t1 (ISBN, LANG, SUBJECT, AUTHOR, TITLE, PUBLISHEr, DATEPUB)
VALUES('9782212090529','fr','général','Alain Michard',
'XML, Langage et Applications','Eyrolles Paris',1998);
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
SUBJECT applications
AUTHOR Jean-Christophe Bernadac
TITLE Construire une application XML
TRANSLATOR NULL
PUBLISHER Eyrolles Paris
DATEPUB 1999
ISBN 9782840825685
LANG fr
SUBJECT applications
AUTHOR William J. Pardi
TITLE XML en Action
TRANSLATOR James Guerin
PUBLISHER Microsoft Press Paris
DATEPUB 1999
ISBN 9782212090529
LANG fr
SUBJECT général
AUTHOR Alain Michard
TITLE XML, Langage et Applications
TRANSLATOR NULL
PUBLISHER Eyrolles Paris
DATEPUB 1998
SELECT LOAD_FILE('MYSQLD_DATADIR/test/xsample2.xml') AS xml;
xml <?xml version="1.0" encoding="UTF-8"?>
<BIBLIO SUBJECT="XML">
<BOOK ISBN="9782212090819" LANG="fr" SUBJECT="applications">
<AUTHOR>
<FIRSTNAME>Jean-Christophe</FIRSTNAME>
<LASTNAME>Bernadac</LASTNAME>
</AUTHOR>
<AUTHOR>
<FIRSTNAME>François</FIRSTNAME>
<LASTNAME>Knab</LASTNAME>
</AUTHOR>
<TITLE>Construire une application XML</TITLE>
<PUBLISHER>
<NAME>Eyrolles</NAME>
<PLACE>Paris</PLACE>
</PUBLISHER>
<DATEPUB>1999</DATEPUB>
</BOOK>
<BOOK ISBN="9782840825685" LANG="fr" SUBJECT="applications">
<AUTHOR>
<FIRSTNAME>William J.</FIRSTNAME>
<LASTNAME>Pardi</LASTNAME>
</AUTHOR>
<TRANSLATOR PREFIX="adapté de l'anglais par">
<FIRSTNAME>James</FIRSTNAME>
<LASTNAME>Guerin</LASTNAME>
</TRANSLATOR>
<TITLE>XML en Action</TITLE>
<PUBLISHER>
<NAME>Microsoft Press</NAME>
<PLACE>Paris</PLACE>
</PUBLISHER>
<DATEPUB>1999</DATEPUB>
</BOOK>
<BOOK ISBN="9782212090529" LANG="fr" SUBJECT="général">
<AUTHOR>Alain Michard</AUTHOR>
<TITLE>XML, Langage et Applications</TITLE>
<PUBLISHER>Eyrolles Paris</PUBLISHER>
<DATEPUB>1998</DATEPUB>
</BOOK>
</BIBLIO>
DROP TABLE t1;
#
# Testing XPath
#
CREATE TABLE t1 (
isbn CHAR(15) FIELD_FORMAT='@ISBN',
language CHAR(2) FIELD_FORMAT='@LANG',
subject CHAR(32) FIELD_FORMAT='@SUBJECT',
authorfn CHAR(20) FIELD_FORMAT='AUTHOR/FIRSTNAME',
authorln CHAR(20) FIELD_FORMAT='AUTHOR/LASTNAME',
title CHAR(32) FIELD_FORMAT='TITLE',
translated CHAR(32) FIELD_FORMAT='TRANSLATOR/@PREFIX',
tranfn CHAR(20) FIELD_FORMAT='TRANSLATOR/FIRSTNAME',
tranln CHAR(20) FIELD_FORMAT='TRANSLATOR/LASTNAME',
publisher CHAR(20) FIELD_FORMAT='PUBLISHER/NAME',
location CHAR(20) FIELD_FORMAT='PUBLISHER/PLACE',
year INT(4) FIELD_FORMAT='DATEPUB'
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=libxml2';
SELECT * FROM t1;
isbn 9782212090819
language fr
subject applications
authorfn Jean-Christophe
authorln Bernadac
title Construire une application XML
translated NULL
tranfn NULL
tranln NULL
publisher Eyrolles
location Paris
year 1999
isbn 9782840825685
language fr
subject applications
authorfn William J.
authorln Pardi
title XML en Action
translated adapté de l'anglais par
tranfn James
tranln Guerin
publisher Microsoft Press
location Paris
year 1999
SELECT isbn, title, translated, tranfn, tranln, location FROM t1
WHERE translated <> '';
isbn 9782840825685
title XML en Action
translated adapté de l'anglais par
tranfn James
tranln Guerin
location Paris
DROP TABLE t1;
#
# Testing that XPath is case sensitive
#
CREATE TABLE t1
(
isbn CHAR(15) FIELD_FORMAT='@isbn'
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample.xml'
TABNAME='BIBLIO' OPTION_LIST='rownode=BOOK,skipnull=1,xmlsup=libxml2';
SELECT * FROM t1;
isbn NULL
isbn NULL
DROP TABLE t1;
#
# Testing character sets
#
CREATE TABLE t1
(
c CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2'
DATA_CHARSET=latin1;
ERROR HY000: DATA_CHARSET='latin1' is not supported for TABLE_TYPE=XML
CREATE TABLE t1
(
c CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2'
DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
Table t1
Create Table CREATE TABLE `t1` (
`c` char(16) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`=XML `FILE_NAME`='latin1.xml' `OPTION_LIST`='xmlsup=libxml2' `DATA_CHARSET`=utf8
SELECT c, HEX(c) FROM t1;
c ÁÂÃÄÅÆÇ
HEX(c) C1C2C3C4C5C6C7
DROP TABLE t1;
CREATE TABLE t1
(
c CHAR(16)
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2';
SELECT c, HEX(c) FROM t1;
c ÁÂÃÄÅÆÇ
HEX(c) C1C2C3C4C5C6C7
DROP TABLE t1;
CREATE TABLE t1
(
c CHAR(16) CHARACTER SET utf8
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2';
SELECT c, HEX(c) FROM t1;
c ÁÂÃÄÅÆÇ
HEX(c) C381C382C383C384C385C386C387
DROP TABLE t1;
#
# Conversion from latin1 to cp1251 produces a warning.
# Question marks are returned.
#
CREATE TABLE t1
(
c CHAR(16) CHARACTER SET cp1251
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='latin1.xml'
OPTION_LIST='xmlsup=libxml2';
SELECT c, HEX(c) FROM t1;
c ???????
HEX(c) 3F3F3F3F3F3F3F
Warnings:
Level Warning
Code 1366
Message Incorrect string value: '\xC3\x81\xC3\x82\xC3\x83...' for column 'c' at row 1
Level Warning
Code 1105
Message Out of range value ÁÂÃÄÅÆÇ for column 'c' at row 1
DROP TABLE t1;
#
# Testing Cyrillic
#
CREATE TABLE t1
(
c CHAR(16) CHARACTER SET utf8
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='cp1251.xml'
OPTION_LIST='xmlsup=libxml2,rownode=b';
SELECT * FROM t1;
c БВГДЕЖЗ
INSERT INTO t1 VALUES ('ИКЛМН');
SELECT c, HEX(c) FROM t1;
c БВГДЕЖЗ
HEX(c) D091D092D093D094D095D096D097
c ИКЛМН
HEX(c) D098D09AD09BD09CD09D
DROP TABLE t1;
CREATE TABLE t1
(
c CHAR(16) CHARACTER SET cp1251
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='cp1251.xml'
OPTION_LIST='xmlsup=libxml2,rownode=b';
SELECT * FROM t1;
c БВГДЕЖЗ
c ИКЛМН
INSERT INTO t1 VALUES ('ОПРСТ');
SELECT c, HEX(c) FROM t1;
c БВГДЕЖЗ
HEX(c) C1C2C3C4C5C6C7
c ИКЛМН
HEX(c) C8CACBCCCD
c ОПРСТ
HEX(c) CECFD0D1D2
DROP TABLE t1;
#
# Testing that the underlying file is created with a proper Encoding
#
CREATE TABLE t1 (node VARCHAR(50))
CHARACTER SET latin1
ENGINE=connect TABLE_TYPE=xml FILE_NAME='t1.xml'
OPTION_LIST='xmlsup=libxml2,rownode=line,encoding=utf-8';
INSERT INTO t1 VALUES (_latin1 0xC0C1C2C3);
SELECT node, hex(node) FROM t1;
node ÀÁÂÃ
hex(node) C0C1C2C3
DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT LEFT(@a,38);
LEFT(@a,38) <?xml version="1.0" encoding="utf-8"?>
SELECT HEX(EXTRACTVALUE(@a,'/t1/line/node'));
HEX(EXTRACTVALUE(@a,'/t1/line/node')) C380C381C382C383
CREATE TABLE t1 (node VARCHAR(50))
CHARACTER SET latin1
ENGINE=connect TABLE_TYPE=xml FILE_NAME='t1.xml'
OPTION_LIST='xmlsup=libxml2,rownode=line,encoding=iso-8859-1';
INSERT INTO t1 VALUES (_latin1 0xC0C1C2C3);
SELECT node, hex(node) FROM t1;
node ÀÁÂÃ
hex(node) C0C1C2C3
DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT LEFT(@a,43);
LEFT(@a,43) <?xml version="1.0" encoding="iso-8859-1"?>
SELECT HEX(EXTRACTVALUE(@a,'/t1/line/node'));
HEX(EXTRACTVALUE(@a,'/t1/line/node')) C0C1C2C3
#
# Testing XML entities
#
CREATE TABLE t1 (node VARCHAR(50))
CHARACTER SET utf8
ENGINE=connect TABLE_TYPE=xml FILE_NAME='t1.xml'
OPTION_LIST='xmlsup=libxml2,rownode=line,encoding=iso-8859-1';
INSERT INTO t1 VALUES (_latin1 0xC0C1C2C3);
INSERT INTO t1 VALUES (_cp1251 0xC0C1C2C3);
INSERT INTO t1 VALUES ('&<>"\'');
SELECT node, hex(node) FROM t1;
node ÀÁÂÃ
hex(node) C380C381C382C383
node АБВГ
hex(node) D090D091D092D093
node &<>"'
hex(node) 263C3E2227
DROP TABLE t1;
SET @a=LOAD_FILE('MYSQLD_DATADIR/test/t1.xml');
SELECT CAST(@a AS CHAR CHARACTER SET latin1);
CAST(@a AS CHAR CHARACTER SET latin1) <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Created by the MariaDB CONNECT Storage Engine-->
<t1>
<line>
<node>ÀÁÂÃ</node>
</line>
<line>
<node>&#1040;&#1041;&#1042;&#1043;</node>
</line>
<line>
<node>&amp;&lt;&gt;"'</node>
</line>
</t1>

View File

@@ -0,0 +1,107 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row';
Warnings:
Warning 1105 No file name. Table will use t1.xml
INSERT INTO t1 VALUES (10);
SELECT * FROM t1;
a
10
UPDATE t1 SET a=20;
SELECT * FROM t1;
a
20
DELETE FROM t1;
SELECT * FROM t1;
a
INSERT INTO t1 VALUES(10);
TRUNCATE TABLE t1;
SELECT * FROM t1;
a
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM v1;
a
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row' FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row' FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
INSERT INTO t1 VALUES (10);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE t1 SET a=20;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
TRUNCATE TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
ALTER TABLE t1 READONLY=1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
ALTER TABLE t1 FILE_NAME='t2.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DROP TABLE t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
SELECT * FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
INSERT INTO v1 VALUES (2);
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row';
Warnings:
Warning 1105 No file name. Table will use t1.xml
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc
#

View File

@@ -0,0 +1,32 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing HTML like XML file
#
CREATE TABLE beers (
`Name` CHAR(16) FIELD_FORMAT='brandName',
`Origin` CHAR(16) FIELD_FORMAT='origin',
`Description` CHAR(32) FIELD_FORMAT='details')
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='beers.xml'
TABNAME='table' OPTION_LIST='xmlsup=libxml2,rownode=tr,colnode=td';
SELECT * FROM beers;
Name Origin Description
Huntsman Bath, UK Wonderful hop, light alcohol
Tuborg Danmark In small bottles
DROP TABLE beers;
#
# Testing HTML file
#
CREATE TABLE coffee (
`Name` CHAR(16),
`Cups` INT(8),
`Type` CHAR(16),
`Sugar` CHAR(4))
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='coffee.htm'
TABNAME='TABLE' HEADER=1 OPTION_LIST='xmlsup=libxml2,Coltype=HTML';
SELECT * FROM coffee;
Name Cups Type Sugar
T. Sexton 10 Espresso No
J. Dinnen 5 Decaf Yes
DROP TABLE coffee;

View File

@@ -0,0 +1,25 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
CREATE TABLE t1 (i INT UNIQUE NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xt1.xml' OPTION_LIST='xmlsup=libxml2,Rownode=N';
ERROR HY000: Table type XML is not indexable
CREATE TABLE t1 (i INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xt1.xml' OPTION_LIST='xmlsup=libxml2,Rownode=N';
DESCRIBE t1;
Field Type Null Key Default Extra
i int(11) NO NULL
ALTER TABLE t1 ADD UNIQUE(i);
ERROR HY000: Table type XML is not indexable
CREATE UNIQUE INDEX i ON t1(i);
ERROR HY000: Table type XML is not indexable
DESCRIBE t1;
Field Type Null Key Default Extra
i int(11) NO NULL
INSERT INTO t1 VALUES(2),(5),(7);
SELECT * FROM t1 WHERE i = 5;
i
5
ALTER TABLE t1 DROP INDEX i;
ERROR 42000: Can't DROP INDEX `i`; check that it exists
DROP INDEX i ON t1;
ERROR 42000: Can't DROP INDEX `i`; check that it exists
DROP TABLE t1;

View File

@@ -0,0 +1,102 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing expanded values
#
CREATE TABLE `bookstore` (
`category` CHAR(16) NOT NULL FIELD_FORMAT='@',
`title` VARCHAR(50) NOT NULL,
`lang` char(2) NOT NULL FIELD_FORMAT='title/@',
`author` VARCHAR(24) NOT NULL,
`year` INT(4) NOT NULL,
`price` DOUBLE(8,2) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=libxml2';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern 2003 49.99
WEB XQuery Kick Start en Per Bothner 2003 49.99
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
WEB XQuery Kick Start en James Linn 2003 49.99
WEB XQuery Kick Start en Vaidyanathan Nagarajan 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
SELECT category, title, price FROM bookstore;
category title price
COOKING Everyday Italian 30.00
CHILDREN Harry Potter 29.99
WEB XQuery Kick Start 49.99
WEB Learning XML 39.95
SELECT category, title, author, price FROM bookstore WHERE author LIKE '%K%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start Kurt Cagle 49.99
WEB Learning XML Erik T. Ray 39.95
SELECT category, title, price FROM bookstore WHERE author LIKE 'J%';
category title price
CHILDREN Harry Potter 29.99
WEB XQuery Kick Start 49.99
WEB XQuery Kick Start 49.99
#
# Limiting expanded values
#
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=libxml2';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern 2003 49.99
WEB XQuery Kick Start en Per Bothner 2003 49.99
WEB XQuery Kick Start en Kurt Cagle 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 3
# One line lost because the where clause is applied only on the first 3 rows
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern 49.99
Warnings:
Warning 1105 Mutiple values limited to 3
#
# Testing concatenated values
#
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=libxml2';
# truncated
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Both 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Truncated author content
# increase author size
ALTER TABLE bookstore MODIFY `author` VARCHAR(128) NOT NULL;
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
#
# Limiting concatenated values
#
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=libxml2';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
CHILDREN Harry Potter en J K. Rowling 2005 29.99
WEB XQuery Kick Start en James McGovern, Per Bothner, Kurt Cagle, James Linn 2003 49.99
WEB Learning XML en Erik T. Ray 2003 39.95
Warnings:
Warning 1105 Mutiple values limited to 4
# The where clause is applied on the concatenated column result
SELECT category, title, author, price FROM bookstore WHERE author LIKE 'J%';
category title author price
CHILDREN Harry Potter J K. Rowling 29.99
WEB XQuery Kick Start James McGovern, Per Bothner, Kurt Cagle, James Linn 49.99
Warnings:
Warning 1105 Mutiple values limited to 4
DROP TABLE bookstore;

View File

@@ -0,0 +1,98 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Testing zipped XML tables
#
CREATE TABLE t1 (
ISBN CHAR(13) NOT NULL FIELD_FORMAT='@',
LANG CHAR(2) NOT NULL FIELD_FORMAT='@',
SUBJECT CHAR(12) NOT NULL FIELD_FORMAT='@',
AUTHOR_FIRSTNAME CHAR(15) NOT NULL FIELD_FORMAT='AUTHOR/FIRSTNAME',
AUTHOR_LASTNAME CHAR(8) NOT NULL FIELD_FORMAT='AUTHOR/LASTNAME',
TRANSLATOR_PREFIX CHAR(24) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/@PREFIX',
TRANSLATOR_FIRSTNAME CHAR(6) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/FIRSTNAME',
TRANSLATOR_LASTNAME CHAR(6) DEFAULT NULL FIELD_FORMAT='TRANSLATOR/LASTNAME',
TITLE CHAR(30) NOT NULL,
PUBLISHER_NAME CHAR(15) NOT NULL FIELD_FORMAT='PUBLISHER/NAME',
PUBLISHER_PLACE CHAR(5) NOT NULL FIELD_FORMAT='PUBLISHER/PLACE',
DATEPUB CHAR(4) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES
OPTION_LIST='entry=xsample2.xml,load=xsample2.xml,rownode=BOOK,xmlsup=libxml2,expand=1,mulnode=AUTHOR';
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
SUBJECT applications
AUTHOR_FIRSTNAME Jean-Christophe
AUTHOR_LASTNAME Bernadac
TRANSLATOR_PREFIX NULL
TRANSLATOR_FIRSTNAME NULL
TRANSLATOR_LASTNAME NULL
TITLE Construire une application XML
PUBLISHER_NAME Eyrolles
PUBLISHER_PLACE Paris
DATEPUB 1999
ISBN 9782212090819
LANG fr
SUBJECT applications
AUTHOR_FIRSTNAME Fran<61>ois
AUTHOR_LASTNAME Knab
TRANSLATOR_PREFIX NULL
TRANSLATOR_FIRSTNAME NULL
TRANSLATOR_LASTNAME NULL
TITLE Construire une application XML
PUBLISHER_NAME Eyrolles
PUBLISHER_PLACE Paris
DATEPUB 1999
ISBN 9782840825685
LANG fr
SUBJECT applications
AUTHOR_FIRSTNAME William J.
AUTHOR_LASTNAME Pardi
TRANSLATOR_PREFIX adapt<70> de l'anglais par
TRANSLATOR_FIRSTNAME James
TRANSLATOR_LASTNAME Guerin
TITLE XML en Action
PUBLISHER_NAME Microsoft Press
PUBLISHER_PLACE Paris
DATEPUB 1999
ISBN 9782212090529
LANG fr
SUBJECT g<>n<EFBFBD>ral
AUTHOR_FIRSTNAME Alain
AUTHOR_LASTNAME Michard
TRANSLATOR_PREFIX NULL
TRANSLATOR_FIRSTNAME NULL
TRANSLATOR_LASTNAME NULL
TITLE XML, Langage et Applications
PUBLISHER_NAME Eyrolles
PUBLISHER_PLACE Paris
DATEPUB 2003
CREATE TABLE t2
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES
OPTION_LIST='xmlsup=libxml2';
SELECT * FROM t2;
ISBN 9782212090819
LANG fr
SUBJECT applications
AUTHOR Jean-Christophe Bernadac
TRANSLATOR NULL
TITLE Construire une application XML
PUBLISHER Eyrolles Paris
DATEPUB 1999
ISBN 9782840825685
LANG fr
SUBJECT applications
AUTHOR William J. Pardi
TRANSLATOR James Guerin
TITLE XML en Action
PUBLISHER Microsoft Press Paris
DATEPUB 1999
ISBN 9782212090529
LANG fr
SUBJECT g<>n<EFBFBD>ral
AUTHOR Alain Michard
TRANSLATOR NULL
TITLE XML, Langage et Applications
PUBLISHER Eyrolles Paris
DATEPUB 2003
DROP TABLE t1,t2;

View File

@@ -1,15 +1,15 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Beginning of grant.inc
#
CREATE USER user@localhost;
GRANT ALL PRIVILEGES ON *.* TO user@localhost;
REVOKE FILE ON *.* FROM user@localhost;
connect user,localhost,user,,;
connection user;
SELECT user();
user()
user@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row';
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=domdoc,rownode=row';
Warnings:
Warning 1105 No file name. Table will use t1.xml
INSERT INTO t1 VALUES (10);
@@ -32,13 +32,15 @@ SELECT * FROM v1;
a
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row' FILE_NAME='t1.EXT';
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=domdoc,rownode=row' FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row' FILE_NAME='t1.EXT';
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=domdoc,rownode=row' FILE_NAME='t1.EXT';
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
@@ -61,10 +63,12 @@ ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
CREATE VIEW v1 AS SELECT * FROM t1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
# Testing a VIEW created with FILE privileges but accessed with no FILE
connection default;
SELECT user();
user()
root@localhost
CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT * FROM t1;
connection user;
SELECT user();
user()
user@localhost
@@ -76,21 +80,25 @@ UPDATE v1 SET a=123;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
DELETE FROM v1;
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
SELECT user();
user()
root@localhost
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=libxml2,rownode=row';
CREATE TABLE t1 (a INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML OPTION_LIST='xmlsup=domdoc,rownode=row';
Warnings:
Warning 1105 No file name. Table will use t1.xml
INSERT INTO t1 VALUES (10);
connection user;
SELECT user();
user()
user@localhost
ALTER TABLE t1 FILE_NAME='t1.EXT';
ERROR 28000: Access denied for user 'user'@'localhost' (using password: NO)
connection default;
DROP TABLE t1;
disconnect user;
DROP USER user@localhost;
#
# End of grant.inc

View File

@@ -1,5 +1,3 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing HTML like XML file
@@ -9,7 +7,7 @@ CREATE TABLE beers (
`Origin` CHAR(16) FIELD_FORMAT='origin',
`Description` CHAR(32) FIELD_FORMAT='details')
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='beers.xml'
TABNAME='table' OPTION_LIST='xmlsup=libxml2,rownode=tr,colnode=td';
TABNAME='table' OPTION_LIST='xmlsup=domdoc,rownode=tr,colnode=td';
SELECT * FROM beers;
Name Origin Description
Huntsman Bath, UK Wonderful hop, light alcohol
@@ -24,7 +22,7 @@ CREATE TABLE coffee (
`Type` CHAR(16),
`Sugar` CHAR(4))
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='coffee.htm'
TABNAME='TABLE' HEADER=1 OPTION_LIST='xmlsup=libxml2,Coltype=HTML';
TABNAME='TABLE' HEADER=1 OPTION_LIST='xmlsup=domdoc,Coltype=HTML';
SELECT * FROM coffee;
Name Cups Type Sugar
T. Sexton 10 Espresso No

View File

@@ -1,9 +1,7 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
CREATE TABLE t1 (i INT UNIQUE NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xt1.xml' OPTION_LIST='Rownode=N';
CREATE TABLE t1 (i INT UNIQUE NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xt1.xml' OPTION_LIST='xmlsup=domdoc,Rownode=N';
ERROR HY000: Table type XML is not indexable
CREATE TABLE t1 (i INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xt1.xml' OPTION_LIST='Rownode=N';
CREATE TABLE t1 (i INT NOT NULL) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xt1.xml' OPTION_LIST='xmlsup=domdoc,Rownode=N';
DESCRIBE t1;
Field Type Null Key Default Extra
i int(11) NO NULL
@@ -19,7 +17,7 @@ SELECT * FROM t1 WHERE i = 5;
i
5
ALTER TABLE t1 DROP INDEX i;
ERROR 42000: Can't DROP 'i'; check that column/key exists
ERROR 42000: Can't DROP INDEX `i`; check that it exists
DROP INDEX i ON t1;
ERROR 42000: Can't DROP 'i'; check that column/key exists
ERROR 42000: Can't DROP INDEX `i`; check that it exists
DROP TABLE t1;

View File

@@ -1,5 +1,3 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
SET NAMES utf8;
#
# Testing expanded values
@@ -11,7 +9,7 @@ CREATE TABLE `bookstore` (
`author` VARCHAR(24) NOT NULL,
`year` INT(4) NOT NULL,
`price` DOUBLE(8,2) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=libxml2';
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='bookstore.xml' OPTION_LIST='expand=1,mulnode=author,limit=6,xmlsup=domdoc';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
@@ -41,7 +39,7 @@ WEB XQuery Kick Start 49.99
#
# Limiting expanded values
#
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=libxml2';
ALTER TABLE bookstore OPTION_LIST='expand=1,mulnode=author,limit=3,xmlsup=domdoc';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00
@@ -62,7 +60,7 @@ Warning 1105 Mutiple values limited to 3
#
# Testing concatenated values
#
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=libxml2';
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=6,xmlsup=domdoc';
# truncated
SELECT * FROM bookstore;
category title lang author year price
@@ -83,7 +81,7 @@ WEB Learning XML en Erik T. Ray 2003 39.95
#
# Limiting concatenated values
#
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=libxml2';
ALTER TABLE bookstore OPTION_LIST='mulnode=author,limit=4,xmlsup=domdoc';
SELECT * FROM bookstore;
category title lang author year price
COOKING Everyday Italian en Giada De Laurentiis 2005 30.00

View File

@@ -1,5 +1,3 @@
Warnings:
Warning 1105 No file name. Table will use t1.xml
#
# Testing zipped XML tables
#
@@ -17,7 +15,7 @@ PUBLISHER_NAME CHAR(15) NOT NULL FIELD_FORMAT='PUBLISHER/NAME',
PUBLISHER_PLACE CHAR(5) NOT NULL FIELD_FORMAT='PUBLISHER/PLACE',
DATEPUB CHAR(4) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES
OPTION_LIST='entry=xsample2.xml,load=xsample2.xml,rownode=BOOK,xmlsup=libxml2,expand=1,mulnode=AUTHOR';
OPTION_LIST='entry=xsample2.xml,load=xsample2.xml,rownode=BOOK,xmlsup=domdoc,expand=1,mulnode=AUTHOR';
SELECT * FROM t1;
ISBN 9782212090819
LANG fr
@@ -69,7 +67,7 @@ PUBLISHER_PLACE Paris
DATEPUB 2003
CREATE TABLE t2
ENGINE=CONNECT TABLE_TYPE=XML FILE_NAME='xsample2.zip' ZIPPED=YES
OPTION_LIST='xmlsup=libxml2';
OPTION_LIST='xmlsup=domdoc';
SELECT * FROM t2;
ISBN 9782212090819
LANG fr

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
--source have_libxml2.inc
--source windows.inc
--echo #
--echo # Testing changing table type (not in-place)
@@ -11,7 +11,7 @@ SELECT * FROM t1;
--echo # This is because the XML top node name defaults to the table name.
--echo # Sure enough the temporary table name begins with '#' and is rejected by XML.
--echo # Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='rownode=row';
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='xmlsup=domdoc,rownode=row';
SELECT * FROM t1;
SHOW CREATE TABLE t1;

View File

@@ -0,0 +1,29 @@
--source have_libxml2.inc
--echo #
--echo # Testing changing table type (not in-place)
--echo #
CREATE TABLE t1 (c INT NOT NULL, d CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=CSV HEADER=1 QUOTED=1;
INSERT INTO t1 VALUES (1,'One'), (2,'Two'), (3,'Three');
SELECT * FROM t1;
--echo # This would fail if the top node name is not specified.
--echo # This is because the XML top node name defaults to the table name.
--echo # Sure enough the temporary table name begins with '#' and is rejected by XML.
--echo # Therefore the top node name must be specified (along with the row nodes name).
ALTER TABLE t1 TABLE_TYPE=XML TABNAME=t1 OPTION_LIST='xmlsup=libxml2,rownode=row';
SELECT * FROM t1;
SHOW CREATE TABLE t1;
--echo # Let us see the XML file
CREATE TABLE t2 (line VARCHAR(100) NOT NULL) ENGINE=CONNECT FILE_NAME='t1.xml';
SELECT * FROM t2;
--echo # NOTE: The first (ignored) row is due to the remaining HEADER=1 option.
--echo # Testing field option modification
ALTER TABLE t1 MODIFY d CHAR(10) NOT NULL FIELD_FORMAT='@', HEADER=0;
SELECT * FROM t1;
SHOW CREATE TABLE t1;
SELECT * FROM t2;
DROP TABLE t1, t2;

View File

@@ -23,9 +23,7 @@ ALTER TABLE t1 OPTION_LIST='subdir=0';
SHOW CREATE TABLE t1;
--replace_result $MYSQLD_DATADIR DATADIR/
SELECT fname, ftype, size FROM t1 ORDER BY fname, ftype, size;
# TODO: add a better error message
--error ER_GET_ERRMSG
--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
INSERT INTO t1 VALUES ('','','','');
DROP TABLE t1;

File diff suppressed because one or more lines are too long

View File

@@ -2,8 +2,8 @@
# MDEV-9739 Assertion `m_status == DA_ERROR || m_status == DA_OK' failed in Diagnostics_area::message() ; connect.xml* tests fail in buildbot
#
--source have_libxml2.inc
--source windows.inc
create table t1 (i int) engine=Connect table_type=XML;
create table t1 (i int) engine=Connect table_type=XML option_list='xmlsup=domdoc';
select * from information_schema.tables where create_options like '%table_type=XML%';
drop table t1;

View File

@@ -0,0 +1,9 @@
#
# MDEV-9739 Assertion `m_status == DA_ERROR || m_status == DA_OK' failed in Diagnostics_area::message() ; connect.xml* tests fail in buildbot
#
--source have_libxml2.inc
create table t1 (i int) engine=Connect table_type=XML option_list='xmlsup=libxml2';
select * from information_schema.tables where create_options like '%table_type=XML%';
drop table t1;

View File

@@ -161,7 +161,7 @@ DROP TABLE t1;
CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year);
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
INSERT IGNORE INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
SELECT * FROM t1;
connection master;

View File

@@ -0,0 +1,11 @@
-- source jdbconn.inc
-- source mongo.inc
eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/Mongo2.jar';
let $DRV= Java;
let $VERS= 2;
let $TYPE= JSON;
let $CONN= CONNECTION='mongodb://localhost:27017' LRECL=4096;
-- source mongo_test.inc
-- source jdbconn_cleanup.inc

View File

@@ -0,0 +1,11 @@
-- source jdbconn.inc
-- source mongo.inc
eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/Mongo3.jar';
let $DRV= Java;
let $VERS= 3;
let $TYPE= JSON;
let $CONN= CONNECTION='mongodb://localhost:27017' LRECL=4096;
-- source mongo_test.inc
-- source jdbconn_cleanup.inc

View File

@@ -0,0 +1,10 @@
-- source mongo.inc
let $DRV= C;
let $VERS= 0;
let $PROJ= {"projection":;
let $ENDP= };
let $TYPE= JSON;
let $CONN= CONNECTION='mongodb://localhost:27017' LRECL=1024;
-- source mongo_test.inc

View File

@@ -0,0 +1,3 @@
let $MONGO= C:/PROGRA~1/MongoDB/Server/3.4/bin/mongo;
let $MONGOIMPORT= C:/PROGRA~1/MongoDB/Server/3.4/bin/mongoimport;

View File

@@ -0,0 +1,9 @@
-- source mongo.inc
let $DRV= C;
let $VERS= 0;
let $PROJ= {"projection":;
let $ENDP= };
let $TYPE= MONGO;
-- source mongo_test.inc

View File

@@ -0,0 +1,10 @@
-- source jdbconn.inc
-- source mongo.inc
eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/Mongo2.jar';
let $DRV= Java;
let $VERS= 2;
let $TYPE= MONGO;
-- source mongo_test.inc
-- source jdbconn_cleanup.inc

View File

@@ -0,0 +1,10 @@
-- source jdbconn.inc
-- source mongo.inc
eval SET GLOBAL connect_class_path='$MTR_SUITE_DIR/std_data/Mongo3.jar';
let $DRV= Java;
let $VERS= 3;
let $TYPE= MONGO;
-- source mongo_test.inc
-- source jdbconn_cleanup.inc

View File

@@ -0,0 +1,203 @@
--echo #
--echo # Test the MONGO table type
--echo #
eval CREATE TABLE t1 (Document varchar(1024) field_format='*')
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants $CONN
OPTION_LIST='Driver=$DRV,Version=$VERS' DATA_CHARSET=utf8;
SELECT * from t1 limit 3;
DROP TABLE t1;
--echo #
--echo # Test catfunc
--echo #
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants CATFUNC=columns
OPTION_LIST='Level=1,Driver=$DRV,Version=$VERS' DATA_CHARSET=utf8 $CONN;
SELECT * from t1;
DROP TABLE t1;
--echo #
--echo # Explicit columns
--echo #
eval CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(255) NOT NULL,
cuisine VARCHAR(255) NOT NULL,
borough VARCHAR(255) NOT NULL,
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants
CONNECTION='mongodb://localhost:27017' LRECL=1024 DATA_CHARSET=utf8
OPTION_LIST='Driver=$DRV,Version=$VERS';
SELECT * FROM t1 LIMIT 10;
DROP TABLE t1;
--echo #
--echo # Test discovery
--echo #
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants
OPTION_LIST='Level=1,Driver=$DRV,Version=$VERS' $CONN DATA_CHARSET=utf8;
SHOW CREATE TABLE t1;
SELECT * FROM t1 LIMIT 5;
DROP TABLE t1;
--echo #
--echo # Dropping a column
--echo #
let $COLIST= $PROJ{"grades":0}$ENDP;
eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants DATA_CHARSET=utf8
COLIST='$COLIST' OPTION_LIST='Driver=$DRV,Version=$VERS,level=0' $CONN;
SELECT * FROM t1 LIMIT 10;
DROP TABLE t1;
--echo #
--echo # Specifying Jpath
--echo #
eval CREATE TABLE t1 (
_id VARCHAR(24) NOT NULL,
name VARCHAR(64) NOT NULL,
cuisine CHAR(200) NOT NULL,
borough CHAR(16) NOT NULL,
street VARCHAR(65) FIELD_FORMAT='address.street',
building CHAR(16) FIELD_FORMAT='address.building',
zipcode CHAR(5) FIELD_FORMAT='address.zipcode',
grade CHAR(1) FIELD_FORMAT='grades.0.grade',
score INT(4) NOT NULL FIELD_FORMAT='grades.0.score',
`date` DATE FIELD_FORMAT='grades.0.date',
restaurant_id VARCHAR(255) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='restaurants' DATA_CHARSET=utf8
OPTION_LIST='Driver=$DRV,Version=$VERS' $CONN;
--vertical_results
SELECT * FROM t1 LIMIT 1;
--horizontal_results
SELECT name, street, score, date FROM t1 LIMIT 5;
SELECT name, cuisine, borough FROM t1 WHERE grade = 'A' LIMIT 10;
SELECT COUNT(*) FROM t1 WHERE grade = 'A';
SELECT * FROM t1 WHERE cuisine = 'English';
SELECT * FROM t1 WHERE score = building;
DROP TABLE t1;
--echo #
--echo # Specifying Filter
--echo #
eval CREATE TABLE t1 (
_id CHAR(24) NOT NULL,
name CHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
restaurant_id CHAR(8) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants DATA_CHARSET=utf8
FILTER='{"cuisine":"French","borough":{"\$ne":"Manhattan"}}'
OPTION_LIST='Driver=$DRV,Version=$VERS' $CONN;
SELECT name FROM t1 WHERE borough = 'Queens';
DROP TABLE t1;
--echo #
--echo # Testing pipeline
--echo #
eval CREATE TABLE t1 (
name VARCHAR(64) NOT NULL,
borough CHAR(16) NOT NULL,
date DATETIME NOT NULL,
grade CHAR(1) NOT NULL,
score INT(4) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='restaurants' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"\$match":{"cuisine":"French"}},{"\$unwind":"\$grades"},{"\$project":{"_id":0,"name":1,"borough":1,"date":"\$grades.date","grade":"\$grades.grade","score":"\$grades.score"}}]}'
OPTION_LIST='Driver=$DRV,Version=$VERS,Pipeline=1' $CONN;
SELECT * FROM t1 LIMIT 10;
SELECT name, grade, score, date FROM t1 WHERE borough = 'Bronx';
DROP TABLE t1;
--echo #
--echo # try level 2 discovery
--echo #
let $COLIST= $PROJ{"cuisine":0}$ENDP;
eval CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME=restaurants
FILTER='{"cuisine":"French","borough":{"\$ne":"Manhattan"}}'
COLIST='$COLIST' $CONN
OPTION_LIST='Driver=$DRV,level=2,version=$VERS';
SHOW CREATE TABLE t1;
IF ($TYPE == MONGO)
{
SELECT name, borough, address_street, grades_0_score AS score FROM t1 WHERE grades_0_grade = 'B';
}
IF ($TYPE == JSON)
{
SELECT name, borough, address_street, grades_score AS score FROM t1 WHERE grades_grade = 'B';
}
DROP TABLE t1;
--echo #
--echo # try CRUD operations
--echo #
--exec $MONGO --eval "db.testcoll.drop()" --quiet
eval CREATE TABLE t1 (_id INT(4) NOT NULL, msg CHAR(64))
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='testcoll'
OPTION_LIST='Driver=$DRV,Version=$VERS' $CONN;
DELETE FROM t1;
INSERT INTO t1 VALUES(0,NULL),(1,'One'),(2,'Two'),(3,'Three');
SELECT * FROM t1;
UPDATE t1 SET msg = 'Deux' WHERE _id = 2;
DELETE FROM t1 WHERE msg IS NULL;
SELECT * FROM t1;
DELETE FROM t1;
DROP TABLE t1;
--exec $MONGO --eval "db.testcoll.drop()" --quiet
--echo #
--echo # List states whose population is equal or more than 10 millions
--echo #
--exec $MONGO --eval "db.cities.drop()" --quiet
--exec $MONGOIMPORT --quiet $MTR_SUITE_DIR/std_data/cities.json
eval CREATE TABLE t1 (
_id char(5) NOT NULL,
city char(16) NOT NULL,
loc_0 double(12,6) NOT NULL `FIELD_FORMAT`='loc.0',
loc_1 char(12) NOT NULL `FIELD_FORMAT`='loc.1',
pop int(11) NOT NULL,
state char(2) NOT NULL)
ENGINE=CONNECT CONNECTION='mongodb://localhost:27017' TABLE_TYPE='MONGO' TABNAME='cities'
OPTION_LIST='Driver=$DRV,Version=$VERS' $CONN DATA_CHARSET='utf8';
--echo # Using SQL for grouping
SELECT state, sum(pop) AS totalPop FROM t1 GROUP BY state HAVING totalPop >= 10000000 ORDER BY totalPop DESC;
DROP TABLE t1;
--echo # Using a pipeline for grouping
eval CREATE TABLE t1 (_id CHAR(2) NOT NULL, totalPop INT(11) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='cities' DATA_CHARSET=utf8
COLIST='{"pipeline":[{"\$group":{"_id":"\$state","totalPop":{"\$sum":"\$pop"}}},{"\$match":{"totalPop":{"\$gte":10000000}}},{"\$sort":{"totalPop":-1}}]}'
OPTION_LIST='Driver=$DRV,Version=$VERS,Pipeline=1' $CONN;
SELECT * FROM t1;
DROP TABLE t1;
--exec $MONGO --eval "db.cities.drop()" --quiet
--echo #
--echo # Test making array
--echo #
eval CREATE TABLE t1 (
_id int(4) NOT NULL,
item CHAR(8) NOT NULL,
prices_0 INT(6) FIELD_FORMAT='prices.0',
prices_1 INT(6) FIELD_FORMAT='prices.1',
prices_2 INT(6) FIELD_FORMAT='prices.2',
prices_3 INT(6) FIELD_FORMAT='prices.3',
prices_4 INT(6) FIELD_FORMAT='prices.4')
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='testcoll' DATA_CHARSET=utf8
OPTION_LIST='Driver=$DRV,Version=$VERS' $CONN;
INSERT INTO t1 VALUES
(1,'journal',87,45,63,12,78),
(2,'notebook',123,456,789,NULL,NULL),
(3,'paper',5,7,3,8,NULL),
(4,'planner',25,71,NULL,44,27),
(5,'postcard',5,7,3,8,NULL);
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Test array aggregation
--echo #
eval CREATE TABLE t1
ENGINE=CONNECT TABLE_TYPE=$TYPE TABNAME='testcoll'
COLIST='{"pipeline":[{"\$project":{"_id":0,"item":1,"total":{"\$sum":"\$prices"},"average":{"\$avg":"\$prices"}}}]}'
OPTION_LIST='Driver=$DRV,Version=$VERS,Pipeline=YES' $CONN;
SELECT * FROM t1;
DROP TABLE t1;
--exec $MONGO --eval "db.testcoll.drop()" --quiet

View File

@@ -19,7 +19,7 @@ SELECT * FROM t1 WHERE command IN ('Warning','Note',
"insert into t1(msg) values('One'),(NULL),('Three')",
"insert into t1 values(2,'Deux') on duplicate key update msg = 'Two'",
"insert into t1(message) values('Four'),('Five'),('Six')",
'insert into t1(id) values(NULL)',
'insert ignore into t1(id) values(NULL)',
"update t1 set msg = 'Four' where id = 4",
'select * from t1');
@@ -31,7 +31,7 @@ CREATE PROCEDURE p1(cmd varchar(512))
READS SQL DATA
SELECT * FROM t1 WHERE command IN ('Warning','Note',cmd);
CALL p1('insert into t1(id) values(NULL)');
CALL p1('insert ignore into t1(id) values(NULL)');
CALL p1('update t1 set msg = "Five" where id = 5');
DROP PROCEDURE p1;
DROP TABLE t1;

View File

@@ -306,7 +306,7 @@ DROP TABLE t1;
CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year);
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
INSERT IGNORE INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23');
SELECT * FROM t1;
connection master;

View File

@@ -1,4 +1,4 @@
-- source include/not_embedded.inc
--source include/not_embedded.inc
let $MYSQLD_DATADIR= `select @@datadir`;
let $PORT= `select @@port`;
@@ -51,20 +51,3 @@ DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
--echo #
--echo # Checking thread TBL tables
--echo #
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v';
SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
SELECT * FROM total order by v desc;
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;

View File

@@ -0,0 +1,89 @@
-- source myconn.inc
connection default;
let $PORT= `select @@port`;
--echo #
--echo # Checking thread TBL tables
--echo #
CREATE TABLE t1 (a int, b char(10));
INSERT INTO t1 VALUES (0,'test00'),(1,'test01'),(2,'test02'),(3,'test03');
SELECT * FROM t1;
connection master;
CREATE TABLE rt2 (a int, b char(10));
INSERT INTO rt2 VALUES (4,'test04'),(5,'test05'),(6,'test06'),(7,'test07');
SELECT * FROM rt2;
connection slave;
CREATE TABLE rt3 (a int, b char(10));
INSERT INTO rt3 VALUES (8,'test08'),(9,'test09'),(10,'test10'),(11,'test11');
SELECT * FROM rt3;
connection default;
--replace_result $MASTER_MYPORT MASTER_PORT
eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@localhost:$MASTER_MYPORT/test/rt2';
SELECT * FROM t2;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE t3 ENGINE=CONNECT TABLE_TYPE=MYSQL
CONNECTION='mysql://root@localhost:$SLAVE_MYPORT/test/rt3';
SELECT * FROM t3;
--replace_result $PORT PORT
eval CREATE TABLE total (a int, b char(10))
ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2,t3'
OPTION_LIST='thread=yes,port=$PORT';
SELECT * FROM total order by a desc;
connection master;
DROP TABLE rt2;
connection slave;
DROP TABLE rt3;
connection default;
DROP TABLE t1,t2,t3,total;
--echo #
--echo # Old thread TBL tables test modified
--echo #
--replace_result $MASTER_MYPORT MASTER_PORT
--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v' OPTION_LIST='port=$MASTER_MYPORT'
SELECT * FROM t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
--eval CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v' OPTION_LIST='port=$SLAVE_MYPORT'
SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
SELECT * FROM total order by v desc;
DROP TABLE t1,t2,total;
--echo #
--echo # Old thread TBL tables test not modified
--echo #
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 11 as v';
SELECT * FROM t1;
CREATE TABLE t2 ENGINE=CONNECT TABLE_TYPE=MYSQL SRCDEF='select 22 as v';
SELECT * FROM t2;
--replace_result $PORT PORT
--eval CREATE TABLE total (v BIGINT(20) UNSIGNED NOT NULL) ENGINE=CONNECT TABLE_TYPE=TBL TABLE_LIST='t1,t2' OPTION_LIST='thread=yes,port=$PORT';
SELECT * FROM total order by v desc;
DROP TABLE total;
DROP TABLE t1;
DROP TABLE t2;
-- source myconn_cleanup.inc

Some files were not shown because too many files have changed in this diff Show More