소스 검색

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 10 년 전
부모
커밋
640ce78f88
4개의 변경된 파일27개의 추가작업 그리고 2개의 파일을 삭제
  1. 1 1
      ecl/hql/hqlgram2.cpp
  2. 1 1
      ecl/hql/hqlutil.cpp
  3. 21 0
      testing/regress/ecl/issue2978.ecl
  4. 4 0
      testing/regress/ecl/key/issue2978.xml

+ 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>