Explorar o código

HPCC-2978 Make IF(cond, unicode_x, unicode_y) variable length

Previously an IF() operator with unicode arguments, where both arguments were
fixed length would force the shorter argument to the length of the longer
argument.  E.g.,
  IF (cond, unicode2_field, U'')
was treated as
  IF (cond, unicode2_field, U'  ')

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday %!s(int64=10) %!d(string=hai) anos
pai
achega
640ce78f88

+ 1 - 1
ecl/hql/hqlgram2.cpp

@@ -3912,7 +3912,7 @@ ITypeInfo *HqlGram::checkPromoteIfType(attribute &a1, attribute &a2)
     ITypeInfo *t2 = a2.queryExprType();
 
     Owned<ITypeInfo> type = ::getPromotedECLType(t1, t2);
-    if (isStringType(type) && (t1->getStringLen() != t2->getStringLen()))
+    if ((isStringType(type) || isUnicodeType(type)) && (t1->getStringLen() != t2->getStringLen()))
         type.setown(getStretchedType(UNKNOWN_LENGTH, type));
 
     ensureType(a1, type);

+ 1 - 1
ecl/hql/hqlutil.cpp

@@ -1492,7 +1492,7 @@ IHqlExpression * createIf(IHqlExpression * cond, IHqlExpression * left, IHqlExpr
     ITypeInfo * leftType = left->queryType();
     ITypeInfo * rightType = right->queryType();
     Owned<ITypeInfo> type = ::getPromotedECLType(leftType, rightType);
-    if (isStringType(type) && (leftType->getStringLen() != rightType->getStringLen()))
+    if ((isStringType(type) || isUnicodeType(type)) && (leftType->getStringLen() != rightType->getStringLen()))
         type.setown(getStretchedType(UNKNOWN_LENGTH, type));
 
     return createValue(no_if, type.getClear(), cond, left, right);

+ 21 - 0
testing/regress/ecl/issue2978.ecl

@@ -0,0 +1,21 @@
+Work1 := RECORD
+  UNSIGNED4 key;
+  UNSIGNED4 pos;
+  UNSIGNED4 len;
+  UNICODE tok;
+END;
+
+ds := DATASET([{1,  1, 3,  u'abc'}
+              ,{1,  4, 1,  u','}
+              ,{1,  6, 1,  u'Z'}
+              ,{2,  1, 3,  u'abc'}
+              ,{2,  5, 3,  u'def'}], Work1);
+
+ Work1 roll1(Work1 cumm, Work1 curr) := TRANSFORM
+  SELF.tok := cumm.tok + IF(cumm.pos + cumm.len < curr.pos, u' ', u'') + curr.tok;
+  SELF.len := cumm.len + IF(cumm.pos + cumm.len < curr.pos, 1, 0) + curr.len;
+  SELF := cumm;
+ END;
+
+d1 := ROLLUP(ds, roll1(LEFT,RIGHT), key, LOCAL);
+OUTPUT(d1);

+ 4 - 0
testing/regress/ecl/key/issue2978.xml

@@ -0,0 +1,4 @@
+<Dataset name='Result 1'>
+ <Row><key>1</key><pos>1</pos><len>6</len><tok>abc, Z</tok></Row>
+ <Row><key>2</key><pos>1</pos><len>7</len><tok>abc def</tok></Row>
+</Dataset>