|
@@ -1683,6 +1683,7 @@ ActivityInstance::ActivityInstance(HqlCppTranslator & _translator, BuildCtx & ct
|
|
|
outputDataset = dataset->queryChild(0);
|
|
|
|
|
|
bool removeXpath = dataset->hasAttribute(noXpathAtom) || (op == no_output && translator.queryOptions().removeXpathFromOutput);
|
|
|
+
|
|
|
LinkedHqlExpr record = queryRecord(outputDataset);
|
|
|
if (removeXpath)
|
|
|
record.setown(removeAttributeFromFields(record, xpathAtom));
|
|
@@ -5027,6 +5028,94 @@ IWUResult * HqlCppTranslator::createWorkunitResult(int sequence, IHqlExpression
|
|
|
return result.getClear();
|
|
|
}
|
|
|
|
|
|
+void getXpathAttrPrefixes(StringArray &prefixes, IHqlExpression *xpathAttr)
|
|
|
+{
|
|
|
+ if (!xpathAttr)
|
|
|
+ return;
|
|
|
+ StringBuffer xpathtext;
|
|
|
+ if (xpathAttr->queryChild(0)->queryValue())
|
|
|
+ xpathAttr->queryChild(0)->queryValue()->getStringValue(xpathtext);
|
|
|
+ if (!xpathtext.length())
|
|
|
+ return;
|
|
|
+ const char *xpath=xpathtext.str();
|
|
|
+ const char *colon = strchr(xpath, ':');
|
|
|
+ while (colon)
|
|
|
+ {
|
|
|
+ const char *finger=colon-1;
|
|
|
+ while (finger>xpath && !strchr("/[ ", *(finger-1)))
|
|
|
+ finger--;
|
|
|
+ StringAttr prefix(finger, colon - finger);
|
|
|
+ if (prefix.length() && prefixes.find(prefix.get())==NotFound)
|
|
|
+ prefixes.append(prefix);
|
|
|
+ colon = strchr(colon+1, ':');
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void gatherXpathPrefixes(StringArray &prefixes, IHqlExpression * record)
|
|
|
+{
|
|
|
+ ForEachChild(i, record)
|
|
|
+ {
|
|
|
+ IHqlExpression * cur = record->queryChild(i);
|
|
|
+ switch (cur->getOperator())
|
|
|
+ {
|
|
|
+ case no_field:
|
|
|
+ {
|
|
|
+ getXpathAttrPrefixes(prefixes, cur->queryAttribute(xpathAtom));
|
|
|
+
|
|
|
+ ITypeInfo * type = cur->queryType();
|
|
|
+ switch (type->getTypeCode())
|
|
|
+ {
|
|
|
+ case type_row:
|
|
|
+ case type_dictionary:
|
|
|
+ case type_table:
|
|
|
+ case type_groupedtable:
|
|
|
+ gatherXpathPrefixes(prefixes, cur->queryRecord());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case no_ifblock:
|
|
|
+ case no_record:
|
|
|
+ gatherXpathPrefixes(prefixes, cur->queryChild(1));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void addDatasetResultXmlNamespaces(IWUResult &result, HqlExprArray &xmlnsAttrs, IHqlExpression *record)
|
|
|
+{
|
|
|
+ StringArray declaredPrefixes;
|
|
|
+ ForEachItemIn(idx, xmlnsAttrs)
|
|
|
+ {
|
|
|
+ IHqlExpression & xmlns = xmlnsAttrs.item(idx);
|
|
|
+ StringBuffer xmlnsPrefix;
|
|
|
+ StringBuffer xmlnsURI;
|
|
|
+ if (xmlns.queryChild(0)->queryValue())
|
|
|
+ xmlns.queryChild(0)->queryValue()->getStringValue(xmlnsPrefix);
|
|
|
+ if (xmlns.queryChild(1)->queryValue())
|
|
|
+ xmlns.queryChild(1)->queryValue()->getStringValue(xmlnsURI);
|
|
|
+ if (xmlnsURI.length())
|
|
|
+ {
|
|
|
+ result.setXmlns(xmlnsPrefix, xmlnsURI);
|
|
|
+ if (xmlnsPrefix.length() && declaredPrefixes.find(xmlnsPrefix)==NotFound)
|
|
|
+ declaredPrefixes.append(xmlnsPrefix);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ StringArray usedPrefixes;
|
|
|
+ if (record)
|
|
|
+ gatherXpathPrefixes(usedPrefixes, record);
|
|
|
+ ForEachItemIn(p, usedPrefixes)
|
|
|
+ {
|
|
|
+ const char *prefix = usedPrefixes.item(p);
|
|
|
+ if (declaredPrefixes.find(prefix)==NotFound)
|
|
|
+ {
|
|
|
+ StringBuffer uri("urn:hpccsystems:ecl:unknown:");
|
|
|
+ uri.append(prefix);
|
|
|
+ result.setXmlns(prefix, uri);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void HqlCppTranslator::buildSetResultInfo(BuildCtx & ctx, IHqlExpression * originalExpr, IHqlExpression * value, ITypeInfo * type, bool isPersist, bool associateResult)
|
|
|
{
|
|
|
IHqlExpression * seq = queryAttributeChild(originalExpr, sequenceAtom, 0);
|
|
@@ -5185,9 +5274,11 @@ void HqlCppTranslator::buildSetResultInfo(BuildCtx & ctx, IHqlExpression * origi
|
|
|
|
|
|
if(wu())
|
|
|
{
|
|
|
+ HqlExprArray xmlnsAttrs;
|
|
|
+ gatherAttributes(xmlnsAttrs, xmlnsAtom, originalExpr);
|
|
|
if (retType == type_row)
|
|
|
{
|
|
|
- Owned<IWUResult> result = createDatasetResultSchema(seq, name, ::queryRecord(schemaType), false, false);
|
|
|
+ Owned<IWUResult> result = createDatasetResultSchema(seq, name, ::queryRecord(schemaType), xmlnsAttrs, false, false);
|
|
|
if (result)
|
|
|
result->setResultTotalRowCount(1);
|
|
|
}
|
|
@@ -5211,6 +5302,8 @@ void HqlCppTranslator::buildSetResultInfo(BuildCtx & ctx, IHqlExpression * origi
|
|
|
fieldName.append('_');
|
|
|
}
|
|
|
|
|
|
+ addDatasetResultXmlNamespaces(*result, xmlnsAttrs, NULL);
|
|
|
+
|
|
|
MemoryBuffer schema;
|
|
|
schema.append(fieldName.str());
|
|
|
schemaType->serialize(schema);
|
|
@@ -7559,7 +7652,9 @@ void HqlCppTranslator::doBuildStmtSetResult(BuildCtx & ctx, IHqlExpression * exp
|
|
|
args.append(*createValue(no_translated, makeSetType(NULL), createValue(no_nullptr, makeSetType(NULL)), getSizetConstant(0)));
|
|
|
args.append(*createTranslatedOwned(createValue(no_nullptr, makeBoolType())));
|
|
|
buildFunctionCall(subctx, setResultSetId, args);
|
|
|
- Owned<IWUResult> result = createDatasetResultSchema(seq, name, value->queryRecord(), true, false);
|
|
|
+ HqlExprArray xmlnsAttrs;
|
|
|
+ gatherAttributes(xmlnsAttrs, xmlnsAtom, expr);
|
|
|
+ Owned<IWUResult> result = createDatasetResultSchema(seq, name, value->queryRecord(), xmlnsAttrs, true, false);
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
@@ -10104,7 +10199,9 @@ ABoundActivity * HqlCppTranslator::doBuildActivityOutputIndex(BuildCtx & ctx, IH
|
|
|
buildRecordEcl(instance->createctx, dataset, "queryRecordECL");
|
|
|
|
|
|
doBuildSequenceFunc(instance->classctx, querySequence(expr), false);
|
|
|
- Owned<IWUResult> result = createDatasetResultSchema(querySequence(expr), queryResultName(expr), dataset->queryRecord(), false, true);
|
|
|
+ HqlExprArray xmlnsAttrs;
|
|
|
+ gatherAttributes(xmlnsAttrs, xmlnsAtom, expr);
|
|
|
+ Owned<IWUResult> result = createDatasetResultSchema(querySequence(expr), queryResultName(expr), dataset->queryRecord(), xmlnsAttrs, false, true);
|
|
|
|
|
|
if (expr->hasAttribute(setAtom))
|
|
|
{
|
|
@@ -10419,7 +10516,9 @@ ABoundActivity * HqlCppTranslator::doBuildActivityOutput(BuildCtx & ctx, IHqlExp
|
|
|
|
|
|
IHqlExpression * outputRecord = instance->meta.queryRecord();
|
|
|
OwnedHqlExpr outputDs = createDataset(no_null, LINK(outputRecord));
|
|
|
- Owned<IWUResult> result = createDatasetResultSchema(seq, queryResultName(expr), outputRecord, (kind != TAKcsvwrite) && (kind != TAKxmlwrite), true);
|
|
|
+ HqlExprArray xmlnsAttrs;
|
|
|
+ gatherAttributes(xmlnsAttrs, xmlnsAtom, expr);
|
|
|
+ Owned<IWUResult> result = createDatasetResultSchema(seq, queryResultName(expr), outputRecord, xmlnsAttrs, (kind != TAKcsvwrite) && (kind != TAKxmlwrite), true);
|
|
|
if (expr->hasAttribute(resultAtom))
|
|
|
result->setResultRowLimit(-1);
|
|
|
|
|
@@ -10586,8 +10685,7 @@ void HqlCppTranslator::finalizeResources()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-IWUResult * HqlCppTranslator::createDatasetResultSchema(IHqlExpression * sequenceExpr, IHqlExpression * name, IHqlExpression * record, bool createTransformer, bool isFile)
|
|
|
+IWUResult * HqlCppTranslator::createDatasetResultSchema(IHqlExpression * sequenceExpr, IHqlExpression * name, IHqlExpression * record, HqlExprArray &xmlnsAttrs, bool createTransformer, bool isFile)
|
|
|
{
|
|
|
//Some spills have no sequence attached
|
|
|
if (!sequenceExpr)
|
|
@@ -10598,6 +10696,8 @@ IWUResult * HqlCppTranslator::createDatasetResultSchema(IHqlExpression * sequenc
|
|
|
if (!result)
|
|
|
return NULL;
|
|
|
|
|
|
+ addDatasetResultXmlNamespaces(*result, xmlnsAttrs, record);
|
|
|
+
|
|
|
MemoryBuffer schema;
|
|
|
OwnedHqlExpr self = getSelf(record);
|
|
|
addSchemaFields(record, schema, self);
|
|
@@ -11027,10 +11127,14 @@ ABoundActivity * HqlCppTranslator::doBuildActivityOutputWorkunit(BuildCtx & ctx,
|
|
|
if (maxsize)
|
|
|
doBuildUnsignedFunction(instance->createctx, "getMaxSize", maxsize->queryChild(0));
|
|
|
|
|
|
+ HqlExprArray xmlnsAttrs;
|
|
|
+ gatherAttributes(xmlnsAttrs, xmlnsAtom, expr);
|
|
|
IHqlExpression * outputRecord = instance->meta.queryRecord();
|
|
|
- Owned<IWUResult> result = createDatasetResultSchema(seq, name, outputRecord, true, false);
|
|
|
+ Owned<IWUResult> result = createDatasetResultSchema(seq, name, outputRecord, xmlnsAttrs, true, false);
|
|
|
if (result)
|
|
|
{
|
|
|
+ SCMStringBuffer debugName;
|
|
|
+ result->getResultName((IStringVal &)debugName);
|
|
|
result->setResultRowLimit(-1);
|
|
|
|
|
|
if (sequence >= 0)
|
|
@@ -11042,6 +11146,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityOutputWorkunit(BuildCtx & ctx,
|
|
|
|
|
|
if (flags.length())
|
|
|
doBuildUnsignedFunction(instance->classctx, "getFlags", flags.str()+1);
|
|
|
+
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -11083,7 +11188,9 @@ void HqlCppTranslator::doBuildStmtOutput(BuildCtx & ctx, IHqlExpression * expr)
|
|
|
if (!name)
|
|
|
name.setown(createQuoted("NULL", LINK(constUnknownVarStringType)));
|
|
|
|
|
|
- Owned<IWUResult> result = createDatasetResultSchema(seq, name, dataset->queryRecord(), true, false);
|
|
|
+ HqlExprArray xmlnsAttrs;
|
|
|
+ gatherAttributes(xmlnsAttrs, xmlnsAtom, expr);
|
|
|
+ Owned<IWUResult> result = createDatasetResultSchema(seq, name, dataset->queryRecord(), xmlnsAttrs, true, false);
|
|
|
|
|
|
CHqlBoundExpr bound;
|
|
|
buildDataset(ctx, dataset, bound, FormatNatural);
|