Pārlūkot izejas kodu

Merge remote-tracking branch 'origin/closedown-4.0.x'

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 gadi atpakaļ
vecāks
revīzija
79749913dd

+ 6 - 3
dali/dfu/dfurun.cpp

@@ -1057,6 +1057,7 @@ public:
         cAbortNotify abortnotify;
         wu->subscribeAbort(&abortnotify);
         bool iskey=false;
+        StringAttr kind;
         bool multiclusterinsert = false;
         bool multiclustermerge = false;
         bool useserverreplicate = false;
@@ -1129,16 +1130,15 @@ public:
                             }
                         }
                     }
-                    const char * kind;
                     if (foreigncopy) {
                         foreignfdesc.setown(queryDistributedFileDirectory().getFileDescriptor(tmp.str(),foreignuserdesc,foreigndalinode));
                         if (!foreignfdesc) {
                             StringBuffer s;
                             throw MakeStringException(-1,"Source file %s could not be found in Dali %s",tmp.str(),foreigndalinode->endpoint().getUrlStr(s).str());
                         }
-                        kind = foreignfdesc->queryProperties().queryProp("@kind");
+                        kind.set(foreignfdesc->queryProperties().queryProp("@kind"));
                         oldRoxiePrefix.set(foreignfdesc->queryProperties().queryProp("@roxiePrefix"));
-                        iskey = kind&&(strcmp(kind,"key")==0);
+                        iskey = strsame("key", kind);
                         if (destination->getWrap()||iskey)
                             destination->setNumPartsOverride(foreignfdesc->numParts());
                         if (options->getPush()) {// need to set ftslave location
@@ -1159,6 +1159,7 @@ public:
                             throw MakeStringException(-1,"Source file %s could not be found",tmp.str());
                         oldRoxiePrefix.set(srcFile->queryAttributes().queryProp("@roxiePrefix"));
                         iskey = isFileKey(srcFile);
+                        kind.set(srcFile->queryAttributes().queryProp("@kind"));
                         if (destination->getWrap()||(iskey&&(cmd==DFUcmd_copy)))    // keys default wrap for copy
                             destination->setNumPartsOverride(srcFile->numParts());
                         if (options->getSubfileCopy()) 
@@ -1258,6 +1259,8 @@ public:
                                 fdesc->queryProperties().setProp("@roxiePrefix", newroxieprefix.str());
                             if (iskey)
                                 fdesc->queryProperties().setProp("@kind", "key");
+                            else if (kind.length()) // JCSMORE may not really need separate "if (iskey)" line above
+                                fdesc->queryProperties().setProp("@kind", kind);
                             if (multiclusterinsert||multiclustermerge) 
                                 multifdesc.setown(fdesc.getClear());
                             else

+ 1 - 1
dali/dfuXRefLib/dfurdir.cpp

@@ -176,7 +176,7 @@ public:
 IPropertyTree *getDirectory(const char * directory, INode * node, unsigned short port)
 {
     //DBGLOG("IPropertyTree * getDirectory");
-    unsigned retries;
+    unsigned retries = 0;
     loop {
         StringAttr nextDir;
         try {

+ 25 - 14
docs/ECLLanguageReference/ECLR_mods/BltInFunc-ROUND.xml

@@ -9,7 +9,8 @@
     </indexterm><indexterm>
       <primary>ROUND function</primary>
     </indexterm>(</emphasis><emphasis>realvalue</emphasis><emphasis
-  role="bold">)</emphasis></para>
+  role="bold">[</emphasis><emphasis>, decimals</emphasis><emphasis
+  role="bold"> ] )</emphasis></para>
 
   <para><informaltable colsep="1" frame="all" rowsep="1">
       <tgroup cols="2">
@@ -25,33 +26,43 @@
           </row>
 
           <row>
+            <entry><emphasis>decimals</emphasis></entry>
+
+            <entry>Optional. An integer specifying the number of decimal
+            places to round to. If omitted, the default is zero (integer
+            result).</entry>
+          </row>
+
+          <row>
             <entry>Return:</entry>
 
-            <entry>ROUND returns a single integer value.</entry>
+            <entry>ROUND returns a single numeric value.</entry>
           </row>
         </tbody>
       </tgroup>
     </informaltable></para>
 
   <para>The <emphasis role="bold">ROUND </emphasis>function returns the
-  rounded integer of the <emphasis>realvalue</emphasis> by using standard
-  arithmetic rounding (decimal portions less than .5 round down and decimal
-  portions greater than or equal to .5 round up).</para>
+  rounded <emphasis>realvalue</emphasis> by using standard arithmetic rounding
+  (decimal portions less than .5 round down and decimal portions greater than
+  or equal to .5 round up).</para>
 
   <para>Example:</para>
 
-  <programlisting>SomeRealValue := 3.14159;
-INTEGER4 MyVal := ROUND(SomeRealValue); // MyVal is 3
+  <programlisting>SomeRealValue1 := 3.14159;
+INTEGER4 MyVal1 := ROUND(SomeRealValue1);   // MyVal1 is 3
+INTEGER4 MyVal2 := ROUND(SomeRealValue1,2); // MyVal2 is 3.14
 
-SomeRealValue := 3.5;
-INTEGER4 MyVal := ROUND(SomeRealValue); // MyVal is 4
+SomeRealValue2 := 3.5;
+INTEGER4 MyVal3 := ROUND(SomeRealValue2); // MyVal is 4
 
-SomeRealValue := -1.3;
-INTEGER4 MyVal := ROUND(SomeRealValue); // MyVal is -1
+SomeRealValue3 := -1.3;
+INTEGER4 MyVal4 := ROUND(SomeRealValue3); // MyVal is -1
 
-SomeRealValue := -1.8;
-INTEGER4 MyVal := ROUND(SomeRealValue); // MyVal is -2
+SomeRealValue4 := -1.8;
+INTEGER4 MyVal5 := ROUND(SomeRealValue4); // MyVal is -2
 </programlisting>
 
-  <para>See Also: <link linkend="ROUNDUP">ROUNDUP</link>, <link linkend="TRUNCATE">TRUNCATE</link></para>
+  <para>See Also: <link linkend="ROUNDUP">ROUNDUP</link>, <link
+  linkend="TRUNCATE">TRUNCATE</link></para>
 </sect1>

+ 81 - 17
docs/ECLLanguageReference/ECLR_mods/Recrd-DATASET.xml

@@ -58,6 +58,9 @@
   <para><emphasis role="bold">DATASET(</emphasis><emphasis> dict
   </emphasis><emphasis role="bold">)</emphasis></para>
 
+  <para><emphasis role="bold">DATASET(</emphasis><emphasis> count, transform
+  </emphasis><emphasis role="bold"> [, DISTRIBUTED ] )</emphasis></para>
+
   <informaltable colsep="1" frame="all" rowsep="1">
     <tgroup cols="2">
       <colspec align="left" colwidth="122.40pt" />
@@ -252,6 +255,28 @@
 
           <entry>The name of a DICTIONARY definition.</entry>
         </row>
+
+        <row>
+          <entry><emphasis>count</emphasis></entry>
+
+          <entry>An integer expression specifying the number of records to
+          create.</entry>
+        </row>
+
+        <row>
+          <entry><emphasis>transform</emphasis></entry>
+
+          <entry>The TRANSFORM function that will create the records. This may
+          take an integer COUNTER parameter.</entry>
+        </row>
+
+        <row>
+          <entry><emphasis role="bold">DISTRIBUTED</emphasis></entry>
+
+          <entry>Optional. Specifies distributing the created records across
+          all nodes of the cluster. If omitted, all records are created on
+          node 1.</entry>
+        </row>
       </tbody>
     </tgroup>
   </informaltable>
@@ -296,6 +321,9 @@
   <para>The eighth form is used to define a DICTIONARY as a DATASET (see
   <emphasis role="bold">DATASET from DICTIONARY </emphasis>below).</para>
 
+  <para>The ninth form is used to create a DATASET using a TRANSFORM function
+  (see <emphasis role="bold">DATASET from TRANSFORM</emphasis> below)</para>
+
   <sect2 id="THOR-FLAT_Files">
     <title>THOR/FLAT Files</title>
 
@@ -422,7 +450,7 @@
     file (or part), and is used for those instances where a usable pointer to
     the record is needed, such as the BUILD function.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>PtblRec := RECORD
   STRING2 State := Person.per_st;
@@ -476,7 +504,8 @@ PtblE := DATASET('~Thor400::RTTEMP::TestFileEncrypted',
       </indexterm>( </emphasis><emphasis>characters</emphasis><emphasis
     role="bold"> ) ]</emphasis><emphasis role="bold"> [, ESCAPE<indexterm>
         <primary>ESCAPE</primary>
-      </indexterm>( </emphasis><emphasis>esc</emphasis><emphasis role="bold"> ) ] [, MAXLENGTH<indexterm>
+      </indexterm>( </emphasis><emphasis>esc</emphasis><emphasis role="bold">
+    ) ] [, MAXLENGTH<indexterm>
         <primary>MAXLENGTH</primary>
       </indexterm>( </emphasis><emphasis>size</emphasis><emphasis role="bold">
     ) ]</emphasis></para>
@@ -571,18 +600,19 @@ PtblE := DATASET('~Thor400::RTTEMP::TestFileEncrypted',
           <row>
             <entry><emphasis role="bold">ESCAPE</emphasis></entry>
 
-            <entry><para>Optional. The string escape character used to indicate 
-            the next character (usually a control character) is part of the data and not to be
-            interpreted as a field or row delimiter. If omitted, the default is a backslash ('\\') 
-            or the escape character specified in the spray operation that put the file on
-            disk.</para></entry>
+            <entry><para>Optional. The string escape character used to
+            indicate the next character (usually a control character) is part
+            of the data and not to be interpreted as a field or row delimiter.
+            If omitted, the default is the escape character specified in the
+            spray operation that put the file on disk (if any).</para></entry>
           </row>
 
           <row>
             <entry><emphasis>esc</emphasis></entry>
 
             <entry><para>A single string constant, or set of string constants,
-            that define the character(s) used to escape control characters.</para></entry>
+            that define the character(s) used to escape control
+            characters.</para></entry>
           </row>
 
           <row>
@@ -647,7 +677,7 @@ PtblE := DATASET('~Thor400::RTTEMP::TestFileEncrypted',
     the default input is in ASCII format with any UNICODE fields in UTF8
     format.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>CSVRecord := RECORD
   UNSIGNED4 person_id;
@@ -757,7 +787,7 @@ file3 := DATASET('MyFile.CSV',
     virtually encompasses the whole thing, then the whole thing will be
     constructed as a referenceable structure that the ECL can get at.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>/* an XML file called "MyFile" contains this XML data:
 &lt;library&gt;
@@ -845,7 +875,7 @@ books := DATASET('MyFile',rform,XML('library/book'));</programlisting>
         <primary>PIPE function</primary>
       </indexterm> and PIPE option on OUTPUT).</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>PtblRec := RECORD
   STRING2 State;
@@ -878,7 +908,7 @@ Ptbl := DATASET('~Thor50::RTTEMP::TestFile',
     by the <emphasis>wuid</emphasis> (workunit ID). This is a feature most
     useful in the Rapid Data Delivery Engine.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>//Named Output DATASET in the same workunit:
 a := OUTPUT(Person(per_st='FL') ,NAMED('FloridaFolk'));
@@ -930,7 +960,7 @@ OUTPUT(ds);</programlisting>
     using inline datasets (see the <emphasis role="bold">Child
     DATASETs</emphasis> discussion).</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>//Inline DATASET using definition values
 myrec := {REAL diff, INTEGER1 reason};
@@ -1015,7 +1045,7 @@ ds := DATASET([T1(123,'Fred','Jones'),
     <para>This form is only used in an expression context. It allows you to
     in-line a single record dataset.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>//the following examples demonstrate 4 ways to do the same thing:
 personRecord := RECORD
@@ -1169,7 +1199,7 @@ OUTPUT(p3);</programlisting>
 
     <programlisting>TABLE(ds, { ds.id, newChildren := ds.children(age != 10); });</programlisting>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>ParentRec := {INTEGER1 NameID, STRING20 Name};
 ParentTable := DATASET([{1,'Kevin'},{2,'Liz'},
@@ -1262,7 +1292,7 @@ r := ROLLUP(fatIn, id, makeChildren(LEFT, RIGHT));</programlisting>
     are primarily for use in BEGINC++ functions or external C++ library
     functions.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>MyRec := {STRING1 Letter};
 SomeFile := DATASET([{'A'},{'B'},{'C'},{'D'},{'E'}],MyRec);
@@ -1368,7 +1398,7 @@ OUTPUT(b_Name);</programlisting>
         <primary>Treating DICTIONARY as a DATASET</primary>
       </indexterm>.</para>
 
-    <para>Example:</para>
+    <para><emphasis role="bold">Example:</emphasis></para>
 
     <programlisting>rec := {STRING color,UNSIGNED1 code, STRING name};
 ColorCodes := DATASET([{'Black' ,0 , 'Fred'},
@@ -1388,4 +1418,38 @@ OUTPUT(ds);         </programlisting>
     linkend="TRANSFORM_Structure">TRANSFORM Structure</link>, <link
     linkend="DICTIONARY">DICTIONARY</link></para>
   </sect2>
+
+  <sect2 id="DATASET_from_TRANSFORM">
+    <title>DATASET from TRANSFORM</title>
+
+    <para><emphasis role="bold">DATASET(</emphasis><emphasis> count, transform
+    </emphasis><emphasis role="bold"> [, DISTRIBUTED ] )</emphasis></para>
+
+    <para>This form uses the<emphasis> transform </emphasis> to create the
+    records. The result type of the <emphasis>transform</emphasis> function
+    determines the structure. The integer COUNTER can be used to number each
+    iteration of the <emphasis>transform</emphasis> function.</para>
+
+    <para><emphasis role="bold">Example:</emphasis></para>
+
+    <programlisting>IMPORT STD;
+msg(UNSIGNED c) := 'Rec ' + (STRING)c + ' on node ' + (STRING)(STD.system.Thorlib.Node()+1);
+
+DS := DATASET(CLUSTERSIZE * 2, 
+              TRANSFORM({STRING line}, 
+                        SELF.line := msg(COUNTER)), 
+              DISTRIBUTED);
+DS;
+/* creates a result like this:
+   Rec 1 on node 1
+   Rec 2 on node 1
+   Rec 3 on node 2
+   Rec 4 on node 2
+   Rec 5 on node 3
+   Rec 6 on node 3 
+*/</programlisting>
+
+    <para>See Also: <link linkend="RECORD_Structure">RECORD Structure</link>,
+    <link linkend="TRANSFORM_Structure">TRANSFORM Structure</link></para>
+  </sect2>
 </sect1>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1529 - 2700
docs/UsingConfigManager/UsingConfigManager.xml


BIN
docs/images/CM-112-1.jpg


BIN
docs/images/CM-112.jpg


BIN
docs/images/CM-Sasha17A.jpg


BIN
docs/images/CM-img02.jpg


BIN
docs/images/CM-img03.jpg


BIN
docs/images/CM-img04-2.jpg


BIN
docs/images/CM-img04-4.jpg


BIN
docs/images/CM-img12.jpg


BIN
docs/images/GS_CMWiz003.jpg


BIN
docs/images/GS_ConfigMgrWiz002.jpg


BIN
docs/images/GS_ConfigMgrWiz004.jpg


BIN
docs/images/LDAP_005.jpg


BIN
docs/images/LDAP_007.jpg


+ 2 - 1
ecl/hqlcpp/hqlhtcpp.cpp

@@ -5302,7 +5302,8 @@ void HqlCppTranslator::buildHashClass(BuildCtx & ctx, const char * name, IHqlExp
     funcctx.addQuoted(s);
 
     bindTableCursor(funcctx, dataset.queryDataset(), "self", dataset.querySide(), dataset.querySelSeq());
-    buildReturn(funcctx, orderExpr);
+    OwnedITypeInfo returnType = makeIntType(4, false);
+    buildReturn(funcctx, orderExpr, returnType);
 
     endNestedClass();
 }

+ 3 - 0
ecl/hthor/hthor.cpp

@@ -735,6 +735,7 @@ void CHThorDiskWriteActivity::setFormat(IFileDescriptor * desc)
     const char *recordECL = helper.queryRecordECL();
     if (recordECL && *recordECL)
         desc->queryProperties().setProp("ECL", recordECL);
+    desc->queryProperties().setProp("@kind", "flat");
 }
 
 void CHThorDiskWriteActivity::checkSizeLimit()
@@ -867,6 +868,7 @@ void CHThorCsvWriteActivity::setFormat(IFileDescriptor * desc)
     desc->queryProperties().setProp("@csvTerminate", rs.setown(csvInfo->getTerminator(0)));
     desc->queryProperties().setProp("@csvEscape", rs.setown(csvInfo->getEscape(0)));
     desc->queryProperties().setProp("@format","utf8n");
+    desc->queryProperties().setProp("@kind", "csv");
 }
 
 //=====================================================================================================
@@ -929,6 +931,7 @@ void CHThorXmlWriteActivity::setFormat(IFileDescriptor * desc)
 {
     desc->queryProperties().setProp("@format","utf8n");
     desc->queryProperties().setProp("@rowTag",rowTag.str());
+    desc->queryProperties().setProp("@kind", "xml");
 }
 
 //=====================================================================================================

+ 29 - 0
ecl/regress/issue10000.ecl

@@ -0,0 +1,29 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2013 HPCC Systems.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+
+inRecord :=
+            RECORD
+unsigned        id;
+decimal8_4      x;
+            END;
+
+
+inTable := dataset('x', inRecord, thor);
+
+output(distribute(inTable, x));
+

+ 22 - 11
plugins/javaembed/javaembed.cpp

@@ -76,7 +76,8 @@ public:
     JavaGlobalState()
     {
         JavaVMInitArgs vm_args; /* JDK/JRE 6 VM initialization arguments */
-        JavaVMOption* options = new JavaVMOption[3];
+
+        StringArray optionStrings;
         const char* origPath = getenv("CLASSPATH");
         StringBuffer newPath;
         newPath.append("-Djava.class.path=").append(origPath);
@@ -88,20 +89,30 @@ public:
             newPath.append(ENVSEPCHAR);
             conf->getProp("classpath", newPath);
         }
+        else
+        {
+            newPath.append(ENVSEPCHAR).append(INSTALL_DIR).append(PATHSEPCHAR).append("classes");
+        }
         newPath.append(ENVSEPCHAR).append(".");
+        optionStrings.append(newPath);
+        if (conf && conf->hasProp("jvmoptions"))
+        {
+            optionStrings.appendList(conf->queryProp("jvmoptions"), ENVSEPSTR);
+        }
 
+        // These may be useful for debugging
+        // optionStrings.append("-Xcheck:jni");
+        // optionStrings.append("-verbose:jni");
 
-        options[0].optionString = (char *) newPath.str();
-        options[1].optionString = (char *) "-Xcheck:jni";
-        options[2].optionString = (char *) "-verbose:jni";
-        vm_args.version = JNI_VERSION_1_6;
-#ifdef _DEBUG
-        vm_args.nOptions = 1;  // set to 3 if you want the verbose...
-#else
-        vm_args.nOptions = 1;
-#endif
+        JavaVMOption* options = new JavaVMOption[optionStrings.length()];
+        ForEachItemIn(idx, optionStrings)
+        {
+            options[idx].optionString = (char *) optionStrings.item(idx);
+        }
+        vm_args.nOptions = optionStrings.length();
         vm_args.options = options;
-        vm_args.ignoreUnrecognized = false;
+        vm_args.ignoreUnrecognized = true;
+        vm_args.version = JNI_VERSION_1_6;
         /* load and initialize a Java VM, return a JNI interface pointer in env */
         JNIEnv *env;       /* receives pointer to native method interface */
         JNI_CreateJavaVM(&javaVM, (void**)&env, &vm_args);

+ 3 - 0
roxie/ccd/ccdserver.cpp

@@ -10858,6 +10858,7 @@ public:
         const char *recordECL = helper.queryRecordECL();
         if (recordECL && *recordECL)
             fileProps.setProp("ECL", recordECL);
+        fileProps.setProp("@kind", "flat"); // default, derivitives may override
     }
 
     virtual IUserDescriptor *queryUserDescriptor() const
@@ -10943,6 +10944,7 @@ public:
         props.setProp("@csvQuote", rs.setown(csvParameters->getQuote(0)));
         props.setProp("@csvTerminate", rs.setown(csvParameters->getTerminator(0)));
         props.setProp("@csvEscape", rs.setown(csvParameters->getEscape(0)));
+        props.setProp("@kind", "csv");
     }
 
     virtual bool isOutputTransformed() const { return true; }
@@ -11014,6 +11016,7 @@ public:
         CRoxieServerDiskWriteActivity::setFileProperties(desc);
         desc->queryProperties().setProp("@format","utf8n");
         desc->queryProperties().setProp("@rowTag",rowTag.get());
+        desc->queryProperties().setProp("@kind", "xml");
     }
 
     virtual bool isOutputTransformed() const { return true; }

+ 1 - 1
system/jlib/jstring.hpp

@@ -508,7 +508,7 @@ extern jlib_decl bool endsWithIgnoreCase(const char* src, const char* dst);
 
 inline bool strieq(const char* s, const char* t) { return stricmp(s,t)==0; }
 inline bool streq(const char* s, const char* t) { return strcmp(s,t)==0; }
-inline bool strsame(const char* s, const char* t) { return (s == t) || (!s && !t && strcmp(s,t)==0); }  // also allow nulls
+inline bool strsame(const char* s, const char* t) { return (s == t) || (s && t && strcmp(s,t)==0); }  // also allow nulls
 
 extern jlib_decl char *j_strtok_r(char *str, const char *delim, char **saveptr);
 extern jlib_decl int j_memicmp (const void *s1, const void *s2, size32_t len); 

+ 1 - 1
thorlcr/activities/diskwrite/thdiskwrite.cpp

@@ -60,8 +60,8 @@ public:
     void done()
     {
         IPropertyTree &props = fileDesc->queryProperties();
-        props.setPropBool("@csv", true);
         props.setProp("@format", "utf8n");
+        props.setProp("@kind", "csv");
         IHThorCsvWriteArg *helper=(IHThorCsvWriteArg *)queryHelper();
         ICsvParameters *csvParameters = helper->queryCsvParameters();
         StringBuffer separator;

+ 1 - 0
thorlcr/activities/keydiff/thkeydiff.cpp

@@ -76,6 +76,7 @@ public:
         OwnedRoxieString outputName(helper->getOutputName());
         fillClusterArray(container.queryJob(), outputName, clusters, groups);
         patchDesc.setown(queryThorFileManager().create(container.queryJob(), outputName, clusters, groups, 0 != (KDPoverwrite & helper->getFlags()), 0, !local, width));
+        patchDesc->queryProperties().setProp("@kind", "keydiff");
     }
     void serializeSlaveData(MemoryBuffer &dst, unsigned slave)
     {

+ 1 - 1
thorlcr/activities/spill/thspill.cpp

@@ -57,7 +57,7 @@ public:
             props.setPropBool("@blockCompressed", true);        
         if (0 != (helper->getFlags() & TDXgrouped))
             fileDesc->queryProperties().setPropBool("@grouped", true);
-
+        props.setProp("@kind", "flat");
         if (container.queryOwner().queryOwner() && (!container.queryOwner().isGlobal())) // I am in a child query
         { // do early, because this will be local act. and will not come back to master until end of owning graph.
             container.queryTempHandler()->registerFile(fname, container.queryOwner().queryGraphId(), helper->getTempUsageCount(), TDXtemporary & helper->getFlags(), getDiskOutputKind(helper->getFlags()), &clusters);

+ 1 - 0
thorlcr/activities/thdiskbase.cpp

@@ -284,6 +284,7 @@ void CWriteMasterBase::init()
             blockCompressed = true;
         if (blockCompressed)
             props.setPropBool("@blockCompressed", true);
+        props.setProp("@kind", "flat");
         if (TAKdiskwrite == container.getKind() && (0 != (diskHelperBase->getFlags() & TDXtemporary)) && container.queryOwner().queryOwner() && (!container.queryOwner().isGlobal())) // I am in a child query
         { // do early, because this will be local act. and will not come back to master until end of owning graph.
             publish();

+ 1 - 0
thorlcr/activities/xmlwrite/thxmlwrite.cpp

@@ -52,6 +52,7 @@ public:
         }
         props.setProp("@rowTag", rowTag.str());
         props.setProp("@format", "utf8n");
+        props.setProp("@kind", "xml");
     }
 };
 

+ 1 - 0
thorlcr/graph/thgraphmaster.cpp

@@ -1470,6 +1470,7 @@ void CJobMaster::saveSpills()
             fillClusterArray(*this, tmpName, clusters, groups);
             Owned<IFileDescriptor> fileDesc = queryThorFileManager().create(*this, tmpName, clusters, groups, true, TDXtemporary|TDWnoreplicate);
             fileDesc->queryProperties().setPropBool("@pausefile", true); // JCSMORE - mark to keep, may be able to distinguish via other means
+            fileDesc->queryProperties().setProp("@kind", "flat");
 
             IPropertyTree &props = fileDesc->queryProperties();
             props.setPropBool("@owned", true);