Przeglądaj źródła

Merge branch 'closedown-5.0.x'

Conflicts:
	version.cmake

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 10 lat temu
rodzic
commit
1b97777429

+ 41 - 14
docs/HPCCClientTools/CT_Mods/CT_Comm_Line_DFU.xml

@@ -25,13 +25,15 @@
       <title>Command Line Interface</title>
 
       <sect2 id="DFUPlusexe">
-        <title><emphasis>dfuplus.exe</emphasis></title>
+        <title><emphasis
+        role="bold">dfuplus</emphasis><emphasis></emphasis><emphasis
+        role="bold">[--version] action=</emphasis><emphasis>operation
+        </emphasis><emphasis
+        role="bold">[</emphasis><emphasis>@filename</emphasis><emphasis
+        role="bold">|</emphasis><emphasis>options</emphasis><emphasis
+        role="bold">]</emphasis></title>
 
-        <para><emphasis role="bold">dfuplus </emphasis><emphasis>
-        </emphasis><emphasis role="bold">action=</emphasis><emphasis>operation
-        </emphasis><emphasis role="bold">[</emphasis><emphasis> @filename
-        </emphasis><emphasis role="bold">| </emphasis><emphasis>options
-        </emphasis><emphasis role="bold">]</emphasis></para>
+        <para></para>
 
         <informaltable colsep="0" frame="none" rowsep="0">
           <tgroup cols="2">
@@ -41,6 +43,12 @@
 
             <tbody>
               <row>
+                <entry><emphasis>--version</emphasis></entry>
+
+                <entry>displays version info</entry>
+              </row>
+
+              <row>
                 <entry><emphasis>operation</emphasis></entry>
 
                 <entry>One of the following actions: spray, despray, copy,
@@ -72,14 +80,33 @@
           </tgroup>
         </informaltable>
 
-        <para>The <emphasis role="bold">dfuplus.exe</emphasis> application
-        accepts command line parameters to send to the Distributed File
-        Utility (DFU) engine via the ESP server. These
-        <emphasis>options</emphasis> can be specified on the command line, in
-        the <emphasis>@filename</emphasis>, in the dfuplus.ini file, or any
-        combination. Command line <emphasis>options</emphasis> override any in
-        the nominated <emphasis>@filename</emphasis>, which in turn override
-        any in the dfuplus.ini file.</para>
+        <para>The <emphasis role="bold">dfuplus</emphasis> executable accepts
+        command line parameters to send to the Distributed File Utility (DFU)
+        engine via the ESP server. These <emphasis>options</emphasis> can be
+        specified on the command line, in the <emphasis>@filename</emphasis>,
+        in the dfuplus.ini file, or any combination. </para>
+
+        <para>Evaluation of options follows this order of precedence:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>command line</para>
+          </listitem>
+
+          <listitem>
+            <para>@filename file</para>
+          </listitem>
+
+          <listitem>
+            <para>ini file</para>
+          </listitem>
+
+          <listitem>
+            <para>default value</para>
+          </listitem>
+        </itemizedlist>
+
+        <para></para>
 
         <sect3>
           <title>General Options:</title>

BIN
docs/images/EPI013.jpg


+ 1 - 4
esp/bindings/SOAP/soaplib/CMakeLists.txt

@@ -63,10 +63,6 @@ include_directories (
 if (WIN32)
     ADD_DEFINITIONS( -D_LIB )
     HPCC_ADD_LIBRARY( soaplib STATIC ${SRCS} )
-    add_dependencies (soaplib 
-        jlib
-        espscm
-        )
 else (WIN32)
     HPCC_ADD_LIBRARY( soaplib SHARED ${SRCS} )
     install ( TARGETS soaplib RUNTIME DESTINATION ${EXEC_DIR} LIBRARY DESTINATION ${LIB_DIR} )
@@ -76,5 +72,6 @@ else (WIN32)
 endif (WIN32)
 add_dependencies (soaplib 
     jlib
+    espscm
     )
 

+ 1 - 1
esp/src/eclwatch/MemberOfWidget.js

@@ -47,7 +47,7 @@ define([
             if (this.inherited(arguments))
                 return;
 
-            this.store = WsAccess.CreateGroupsStore(params.username);
+            this.store = WsAccess.CreateGroupsStore(params.username, false);
             this.grid.setStore(this.store);
             this._refreshActionState();
         },

+ 1 - 1
esp/src/eclwatch/MembersWidget.js

@@ -47,7 +47,7 @@ define([
             if (this.inherited(arguments))
                 return;
 
-            this.store = WsAccess.CreateUsersStore(params.groupname);
+            this.store = WsAccess.CreateUsersStore(params.groupname, false);
             this.grid.setStore(this.store);
             this._refreshActionState();
         },

+ 2 - 6
esp/src/eclwatch/UserQueryWidget.js

@@ -379,7 +379,7 @@ define([
         //  Groups  ---
         initGroupsGrid: function () {
             this.initGroupsContextMenu();
-            var store = WsAccess.CreateGroupsStore();
+            var store = WsAccess.CreateGroupsStore(null, true);
             this.groupsGrid = declare([ESPUtil.Grid(false, true)])({
                 store: store,
                 columns: {
@@ -388,7 +388,6 @@ define([
                         label: " "
                     }, "checkbox"),
                     name: {
-                        sortable: false,
                         label: this.i18n.GroupName
                     }
                 }
@@ -460,7 +459,7 @@ define([
         //  Users  ---
         initUsersGrid: function () {
             this.initUsersContextMenu();
-            this.usersStore = WsAccess.CreateUsersStore();
+            this.usersStore = WsAccess.CreateUsersStore(null, true);
             this.usersGrid = declare([ESPUtil.Grid(false, true)])({
                 store: this.usersStore,
                 query: this.filter.toObject(),
@@ -471,16 +470,13 @@ define([
                     },"checkbox"),
                     username: {
                         width: 180,
-                        sortable: false,
                         label: this.i18n.Username
                     },
                     fullname: {
-                        sortable: false,
                         label: this.i18n.FullName
                     },
                     passwordexpiration: {
                         width: 180,
-                        sortable: false,
                         label: this.i18n.PasswordExpiration
                     }
                 }

+ 7 - 8
esp/src/eclwatch/WUDetailsWidget.js

@@ -84,8 +84,8 @@ define([
         graphsWidgetLoaded: false,
         logsWidget: null,
         logsWidgetLoaded: false,
-        playgroundWidget: null,
-        playgroundWidgetLoaded: false,
+        eclWidget: null,
+        eclWidgetLoaded: false,
         xmlWidget: null,
         xmlWidgetLoaded: false,
         publishForm: null,
@@ -108,7 +108,7 @@ define([
             this.timersWidget = registry.byId(this.id + "_Timers");
             this.graphsWidget = registry.byId(this.id + "_Graphs");
             this.logsWidget = registry.byId(this.id + "_Logs");
-            this.playgroundWidget = registry.byId(this.id + "_Playground");
+            this.eclWidget = registry.byId(this.id + "_ECL");
             this.xmlWidget = registry.byId(this.id + "_XML");
             this.publishForm = registry.byId(this.id + "PublishForm");
             this.zapDescription = registry.byId(this.id + "ZapDescription");
@@ -285,11 +285,10 @@ define([
                 this.logsWidget.init({
                     Wuid: this.wu.Wuid
                 });
-            } else if (currSel.id == this.playgroundWidget.id && !this.playgroundWidgetLoaded) {
-                this.playgroundWidgetLoaded = true;
-                this.playgroundWidget.init({
-                    Wuid: this.wu.Wuid,
-                    Target: this.wu.Cluster
+            } else if (currSel.id == this.eclWidget.id && !this.eclWidgetLoaded) {
+                this.eclWidgetLoaded = true;
+                this.eclWidget.init({
+                    Wuid: this.wu.Wuid
                 });
             } else if (currSel.id == this.xmlWidget.id && !this.xmlWidgetLoaded) {
                 this.xmlWidgetLoaded = true;

+ 2 - 2
esp/src/eclwatch/templates/DFUQueryWidget.html

@@ -16,8 +16,8 @@
                                     <legend>${i18n.Source}</legend>
                                     <div data-dojo-type="hpcc.TableContainer">
                                         <input name="sourceDali" title="${i18n.Dali}:" style="width:100%" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                        <input name="srcusername" title="${i18n.UserID}:" style="width:100%" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                        <input name="srcpassword" title="${i18n.Password}:" style="width:100%" required="true" type="password" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input name="srcusername" title="${i18n.UserID}:" style="width:100%" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input name="srcpassword" title="${i18n.Password}:" style="width:100%" type="password" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
                                         <input name="sourceLogicalName" title="${i18n.LogicalName}:" style="width:100%" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
                                     </div>
                                 </div>

+ 1 - 1
esp/src/eclwatch/templates/WUDetailsWidget.html

@@ -111,7 +111,7 @@
             </div>
             <div id="${id}_Logs" title="${i18n.Helpers}" data-dojo-props="delayWidget: 'LogsWidget', disabled: true" data-dojo-type="DelayLoadWidget">
             </div>
-            <div id="${id}_Playground" title="${i18n.Playground}" data-dojo-props="delayWidget: 'ECLPlaygroundWidget'" data-dojo-type="DelayLoadWidget">
+            <div id="${id}_ECL" title="${i18n.ECL}" data-dojo-props="delayWidget: 'ECLSourceWidget'" data-dojo-type="DelayLoadWidget">
             </div>
             <div id="${id}_XML" title="${i18n.XML}" data-dojo-props="delayProps: {WUXml: true}, delayWidget: 'ECLSourceWidget'" data-dojo-type="DelayLoadWidget">
             </div>

+ 24 - 21
esp/src/eclwatch/ws_access.js

@@ -22,12 +22,13 @@ define([
     "dojo/store/Memory",
     "dojo/store/Observable",
     "dojo/store/util/QueryResults",
+    "dojo/store/util/SimpleQueryEngine",
     "dojo/topic",
 
     "hpcc/ESPRequest",
     "hpcc/ESPUtil"
 
-], function (declare, lang, arrayUtil, Deferred, all, Memory, Observable, QueryResults, topic,
+], function (declare, lang, arrayUtil, Deferred, all, Memory, Observable, QueryResults, SimpleQueryEngine, topic,
     ESPRequest, ESPUtil) {
 
     var UsersStore = declare([Memory], {
@@ -66,10 +67,9 @@ define([
                         isMember: groupUsers[item.username] ? true : false
                     }));
                 }, this);
-                this.setData(data);
-                return arrayUtil.map(data, function (item) {
-                    return item;
-                });
+                options = options || {};
+                this.setData(SimpleQueryEngine({}, { sort: options.sort })(data));
+                return this.data;
             }));
             return QueryResults(results);
         },
@@ -147,10 +147,9 @@ define([
                         }));
                     }
                 }, this);
-                this.setData(data);
-                return arrayUtil.map(data, function (item) {
-                    return item;
-                });
+                options = options || {};
+                this.setData(SimpleQueryEngine({}, { sort: options.sort })(data));
+                return this.data;
             }));
             return QueryResults(results);
         },
@@ -232,10 +231,9 @@ define([
                         deny_full: accountPermission ? accountPermission.deny_full : false
                     }));
                 }, this);
-                this.setData(data);
-                return arrayUtil.map(data, function (item) {
-                    return item;
-                });
+                options = options || {};
+                this.setData(SimpleQueryEngine({}, { sort: options.sort })(data));
+                return this.data;
             }));
             return QueryResults(results);
         },
@@ -331,10 +329,9 @@ define([
                         }));
                     }, this);
                 }
-                this.setData(data);
-                return arrayUtil.map(data, function (item) {
-                    return item;
-                });
+                options = options || {};
+                this.setData(SimpleQueryEngine({}, { sort: options.sort })(data));
+                return this.data;
             }));
             return QueryResults(results);
         }
@@ -464,16 +461,22 @@ define([
             });
         },
 
-        CreateUsersStore: function (groupname) {
+        CreateUsersStore: function (groupname, observable) {
             var store = new UsersStore();
             store.groupname = groupname;
-            return Observable(store);
+            if (observable) {
+                return Observable(store);
+            }
+            return store;
         },
 
-        CreateGroupsStore: function (username) {
+        CreateGroupsStore: function (username, observable) {
             var store = new GroupsStore();
             store.username = username;
-            return Observable(store);
+            if (observable) {
+                return Observable(store);
+            }
+            return store;
         },
 
         CreatePermissionsStore: function (groupname, username) {

+ 4 - 1
initfiles/examples/embed/java-stream.ecl

@@ -47,11 +47,14 @@ OUTPUT(jpassrec(ret));  // Passes an ECL record to a Java function
 // where the fields of the object in question are mapped by name to the fields in the ECL record.
 // When passing an iterator, we use a modified form of the function signature in the IMPORT statement, using a < to indicate "Iterator of"
 // followed by the name of the class of the objects that the iterator is to return. This is the one case where the output of javap -s cannot be used
-// directly to provide the signature of the java function being called.
+// directly to provide the signature of the java function being called. We can also use the "extended" signature of the method that is output by
+// javap -s -v, of the form 'JavaCat.passDataset:(Ljava/util/Iterator<LJavaCat;>;)I'
+//
 // To return a dataset, an iterator must be returned.
 
 INTEGER passDataset(LINKCOUNTED DATASET(jret) d) :=
   IMPORT(java, 'JavaCat.passDataset:(<LJavaCat;)I'); // Calls int passDataset(Iterator<JavaCat> d)
+// Note we could also use 'Ljava/util/Iterator<LJavaCat;>;)I' as the signature, but not 'Ljava/util/Iterator;)I' which is the signature output by javap -s
 
 DATASET(jret) passDataset2(LINKCOUNTED DATASET(jret) d) :=
   IMPORT(java, 'JavaCat.passDataset2:([LJavaCat;)Ljava/util/Iterator;'); // Calls Iterator<JavaCat> passDataset2(JavaCat d[])

+ 18 - 17
initfiles/examples/embed/mysql-simple.ecl

@@ -27,24 +27,25 @@ init := DATASET([{'name1', 1, true, 1.2, 3.4, D'aa55aa55', 1234567.89, U'Straße
 
 // Set up the MySQL database
 // Enable remote access to your MySQL DB Server to use its DNS name or IP, else use localhost or 127.0.0.1
+// If port argument is omitted, it defaults to 3306
 
-drop() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+drop() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   DROP TABLE IF EXISTS tbl1;
 ENDEMBED;
 
-create() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+create() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   CREATE TABLE tbl1 ( name VARCHAR(20), value INT, boolval TINYINT, r8 DOUBLE, r4 FLOAT, d BLOB, ddd DECIMAL(10,2), u1 VARCHAR(10), u2 VARCHAR(10) );
 ENDEMBED;
 
 // Initialize the MySQL table, passing in the ECL dataset to provide the rows
 
-initialize(dataset(childrec) values) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+initialize(dataset(childrec) values) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   INSERT INTO tbl1 values (?, ?, ?, ?, ?, ?, ?, ?, ?);
 ENDEMBED;
 
 // Add an additional row containing NULL values, to test that they are handled properly when read in ECL
 
-initializeNulls() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+initializeNulls() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   INSERT INTO tbl1 (name) values ('nulls');
 ENDEMBED;
 
@@ -56,13 +57,13 @@ ENDEMBED;
 
 // Returning a dataset
 
-dataset(childrec) testMySQLDS() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+dataset(childrec) testMySQLDS() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT * from tbl1;
 ENDEMBED;
 
 // Returning a single row
 
-childrec testMySQLRow() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+childrec testMySQLRow() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT * from tbl1 LIMIT 1;
 ENDEMBED;
 
@@ -77,45 +78,45 @@ childrec testMySQLParms(
    real4 r4,
    DATA d,
    UTF8 u1,
-   UNICODE8 u2) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+   UNICODE8 u2) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT * from tbl1 WHERE name=? AND value=? AND boolval=? AND r8=? AND r4=? AND d=? AND u1=? AND u2=?;
 ENDEMBED;
 
 // Returning scalars
 
-string testMySQLString() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+string testMySQLString() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(name) from tbl1;
 ENDEMBED;
 
-dataset(childrec) testMySQLStringParam(string filter) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+dataset(childrec) testMySQLStringParam(string filter) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT * from tbl1 where name = ?;
 ENDEMBED;
 
-integer testMySQLInt() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+integer testMySQLInt() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(value) from tbl1;
 ENDEMBED;
 
-boolean testMySQLBool() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+boolean testMySQLBool() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(boolval) from tbl1;
 ENDEMBED;
 
-real8 testMySQLReal8() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+real8 testMySQLReal8() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(r8) from tbl1;
 ENDEMBED;
 
-real4 testMySQLReal4() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+real4 testMySQLReal4() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(r4) from tbl1;
 ENDEMBED;
 
-data testMySQLData() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+data testMySQLData() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(d) from tbl1;
 ENDEMBED;
 
-UTF8 testMySQLUtf8() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+UTF8 testMySQLUtf8() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(u1) from tbl1;
 ENDEMBED;
 
-UNICODE testMySQLUnicode() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+UNICODE testMySQLUnicode() := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT max(u2) from tbl1;
 ENDEMBED;
 
@@ -129,7 +130,7 @@ stringrec extractName(childrec l) := TRANSFORM
   SELF := l;
 END;
 
-dataset(childrec) testMySQLDSParam(dataset(stringrec) inrecs) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'))
+dataset(childrec) testMySQLDSParam(dataset(stringrec) inrecs) := EMBED(mysql : user('rchapman'),database('test'),server('127.0.0.1'), port('3306'))
   SELECT * from tbl1 where name = ?;
 ENDEMBED;
 

+ 44 - 26
plugins/javaembed/javaembed.cpp

@@ -1314,10 +1314,17 @@ public:
             {
                 if (*finger == '<')
                 {
-                    javaSignature.append("Ljava/util/Iterator;");
-                    finger = strchr(finger, ';');
-                    if (!finger)
-                        throw MakeStringException(MSGAUD_user, 0, "javaembed: Invalid java function signature %s", signature);
+                    // If there is a corresponding >, assume it's the 'extended' form and just strip out the bit from < to >
+                    const char *close = strchr(finger, '>');
+                    if (close)
+                        finger = close;
+                    else
+                    {
+                        javaSignature.append("Ljava/util/Iterator;");
+                        finger = strchr(finger, ';');
+                        if (!finger)
+                            throw MakeStringException(MSGAUD_user, 0, "javaembed: Invalid java function signature %s", signature);
+                    }
                 }
                 else
                     javaSignature.append(*finger);
@@ -2123,18 +2130,40 @@ public:
     virtual void bindDatasetParam(const char *name, IOutputMetaData & metaVal, IRowStream * val)
     {
         jvalue v;
-        if (*argsig == '[')
+        char argsigStart = *argsig;
+        switch (argsigStart)
         {
+        case '[':
+        case '<':
             ++argsig;
-            // At present, dataset parameters have to map to arrays. May support iterators later
-            if (*argsig != 'L')  // should tell us the type of the object we need to create to pass in
+            break;
+        case 'L':
+            if (strncmp(argsig, "Ljava/util/Iterator<", 20) == 0)
+            {
+                argsig += 20;
+                break;
+            }
+            /* no break */
+        default:
+            typeError("DATASET");
+        }
+        if (*argsig != 'L')  // should tell us the type of the object we need to create to pass in
+            typeError("DATASET");
+        // Class name is from the char after the L up to the first ;
+        const char *tail = strchr(argsig, ';');
+        if (!tail)
+            typeError("RECORD");
+        StringAttr className(argsig+1, tail - (argsig+1));
+        argsig = tail+1;
+        if (argsigStart=='L')
+        {
+            if (argsig[0] != '>' || argsig[1] != ';')
                 typeError("DATASET");
-            // Class name is from the char after the L up to the first ;
-            const char *tail = strchr(argsig, ';');
-            if (!tail)
-                typeError("RECORD");
-            StringAttr className(argsig+1, tail - (argsig+1));
-            argsig = tail+1;
+            argsig += 2;
+        }
+        if (argsigStart=='[')
+        {
+            // Pass in an array of objects
             PointerArrayOf<_jobject> allRows;
             const RtlTypeInfo *typeInfo = metaVal.queryTypeInfo();
             assertex(typeInfo);
@@ -2156,18 +2185,9 @@ public:
             }
             v.l = array;
         }
-        else if (*argsig == '<') // An extension to the Java signatures, used to indicate
-                                  // that we will pass an iterator that generates objects of the specified type
+        else
         {
-            ++argsig;
-            if (*argsig != 'L')  // should tell us the type of the object we need to create to pass in
-                typeError("DATASET");
-            // Class name is from the char after the L up to the first ;
-            const char *tail = strchr(argsig, ';');
-            if (!tail)
-                typeError("RECORD");
-            StringAttr className(argsig+1, tail - (argsig+1));
-            argsig = tail+1;
+            // Pass in an iterator
             // Create a java object of type com.HPCCSystems.HpccUtils - this acts as a proxy for the iterator
             sharedCtx->JNIenv->ExceptionClear();
             jclass proxyClass = sharedCtx->JNIenv->FindClass("com/HPCCSystems/HpccUtils");
@@ -2183,8 +2203,6 @@ public:
             sharedCtx->checkException();
             v.l = proxy;
         }
-        else
-            typeError("DATASET");
         addArg(v);
     }
 

+ 6 - 1
plugins/mysql/mysqlembed.cpp

@@ -732,10 +732,12 @@ public:
     virtual bool processBeginSet(const RtlFieldInfo * field, unsigned numElements, bool isAll, const byte *data)
     {
         UNSUPPORTED("SET fields");
+        return false;
     }
     virtual bool processBeginDataset(const RtlFieldInfo * field, unsigned numRows)
     {
         UNSUPPORTED("Nested datasets");
+        return false;
     }
     virtual bool processBeginRow(const RtlFieldInfo * field)
     {
@@ -875,6 +877,7 @@ public:
         const char *user = "";
         const char *password = "";
         const char *database = "";
+        unsigned port = 0;
         StringArray opts;
         opts.appendList(options, ",");
         ForEachItemIn(idx, opts)
@@ -887,6 +890,8 @@ public:
                 val++;
                 if (stricmp(optName, "server")==0)
                     server = val;   // Note that lifetime of val is adequate for this to be safe
+                else if (stricmp(optName, "port")==0)
+                    port = atoi(val);
                 else if (stricmp(optName, "user")==0)
                     user = val;
                 else if (stricmp(optName, "password")==0)
@@ -896,7 +901,7 @@ public:
             }
         }
         conn.setown(new MySQLConnection(mysql_init(NULL)));
-        if (!mysql_real_connect(*conn, server, user, password, database, 0, NULL, 0))
+        if (!mysql_real_connect(*conn, server, user, password, database, port, NULL, 0))
         {
             VStringBuffer err("mysql: failed to connect (%s)", mysql_error(*conn));
             rtlFail(0, err.str());

+ 5 - 0
roxie/ccd/ccdserver.cpp

@@ -23149,6 +23149,7 @@ public:
         CRoxieServerIndexReadBaseActivity::start(parentExtractSize, parentExtract, paused);
         rowLimit = readHelper.getRowLimit();
         keyedLimit = readHelper.getKeyedLimit();
+        choosenLimit = readHelper.getChooseNLimit();
         if (!paused)
             processAllKeys();
     }
@@ -23174,6 +23175,8 @@ public:
                 Owned<CRowArrayMessageResult> result = new CRowArrayMessageResult(ctx->queryRowManager(), meta.isVariableSize());
                 do
                 {
+                    if (accepted>=choosenLimit)
+                        break;
                     rowBuilder.ensureRow();
                     try
                     {
@@ -23195,6 +23198,8 @@ public:
                 } while (readHelper.next());
                 remote.injectResult(result.getClear());
                 callback.finishedRow();
+                if (accepted>=choosenLimit)
+                    return true;
             }
         }
         return false;