hive-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hashut...@apache.org
Subject svn commit: r1291633 - in /hive/trunk/ql/src: java/org/apache/hadoop/hive/ql/udf/ test/queries/clientpositive/ test/results/clientpositive/
Date Tue, 21 Feb 2012 07:42:38 GMT
Author: hashutosh
Date: Tue Feb 21 07:42:37 2012
New Revision: 1291633

URL: http://svn.apache.org/viewvc?rev=1291633&view=rev
Log:
HIVE-2792: SUBSTR(CAST(<string> AS BINARY)) produces unexpected results (navis via hashutosh)

Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFSubstr.java
    hive/trunk/ql/src/test/queries/clientpositive/ba_table_udfs.q
    hive/trunk/ql/src/test/queries/clientpositive/udf_substr.q
    hive/trunk/ql/src/test/results/clientpositive/ba_table_udfs.q.out
    hive/trunk/ql/src/test/results/clientpositive/udf_substr.q.out

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFSubstr.java
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFSubstr.java?rev=1291633&r1=1291632&r2=1291633&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFSubstr.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFSubstr.java Tue Feb 21 07:42:37
2012
@@ -24,6 +24,8 @@ import org.apache.hadoop.io.BytesWritabl
 import org.apache.hadoop.io.IntWritable;
 import org.apache.hadoop.io.Text;
 
+import java.util.Arrays;
+
 /**
  * UDFSubstr.
  *
@@ -43,9 +45,12 @@ import org.apache.hadoop.io.Text;
     + "  > SELECT _FUNC_('Facebook', 5, 1) FROM src LIMIT 1;\n"
     + "  'b'")
 public class UDFSubstr extends UDF {
+
+  private final int[] index;
   private final Text r;
 
   public UDFSubstr() {
+    index = new int[2];
     r = new Text();
   }
 
@@ -60,29 +65,39 @@ public class UDFSubstr extends UDF {
       return r;
     }
 
-    String s = t.toString();
-    if ((Math.abs(pos.get()) > s.length())) {
+    int[] index = makeIndex(pos.get(), len.get(), t.getLength());
+    if (index == null) {
       return r;
     }
 
+    String s = t.toString();
+    r.set(s.substring(index[0], index[1]));
+    return r;
+  }
+
+  private int[] makeIndex(int pos, int len, int inputLen) {
+    if ((Math.abs(pos) > inputLen)) {
+      return null;
+    }
+
     int start, end;
 
-    if (pos.get() > 0) {
-      start = pos.get() - 1;
-    } else if (pos.get() < 0) {
-      start = s.length() + pos.get();
+    if (pos > 0) {
+      start = pos - 1;
+    } else if (pos < 0) {
+      start = inputLen + pos;
     } else {
       start = 0;
     }
 
-    if ((s.length() - start) < len.get()) {
-      end = s.length();
+    if ((inputLen - start) < len) {
+      end = inputLen;
     } else {
-      end = start + len.get();
+      end = start + len;
     }
-
-    r.set(s.substring(start, end));
-    return r;
+    index[0] = start;
+    index[1] = end;
+    return index;
   }
 
   private final IntWritable maxValue = new IntWritable(Integer.MAX_VALUE);
@@ -91,21 +106,22 @@ public class UDFSubstr extends UDF {
     return evaluate(s, pos, maxValue);
   }
 
-  public BytesWritable evaluate(BytesWritable bw, IntWritable pos, IntWritable len){
+  public BytesWritable evaluate(BytesWritable bw, IntWritable pos, IntWritable len) {
 
-    if ((null == bw) || (null == pos) || (null == len)) {
+    if ((bw == null) || (pos == null) || (len == null)) {
       return null;
-}
+    }
 
-    BytesWritable outgoing = new BytesWritable();
+    if ((len.get() <= 0)) {
+      return new BytesWritable();
+    }
 
-    if ((len.get() <= 0) || (pos.get() < 0) || (pos.get() > bw.getLength())) {
-      return outgoing;
+    int[] index = makeIndex(pos.get(), len.get(), bw.getLength());
+    if (index == null) {
+      return new BytesWritable();
     }
 
-    byte[] underlying = bw.getBytes();
-    outgoing.set(underlying, pos.get(), len.get());
-    return outgoing;
+    return new BytesWritable(Arrays.copyOfRange(bw.getBytes(), index[0], index[1]));
   }
 
   public BytesWritable evaluate(BytesWritable bw, IntWritable pos){

Modified: hive/trunk/ql/src/test/queries/clientpositive/ba_table_udfs.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/ba_table_udfs.q?rev=1291633&r1=1291632&r2=1291633&view=diff
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/ba_table_udfs.q (original)
+++ hive/trunk/ql/src/test/queries/clientpositive/ba_table_udfs.q Tue Feb 21 07:42:37 2012
@@ -8,7 +8,9 @@ SELECT
   LENGTH(CAST(src.key AS BINARY)),
   LENGTH(CAST(src.value AS BINARY)),
   CONCAT(CAST(src.key AS BINARY), CAST(src.value AS BINARY)),
-  SUBSTR(CAST(src.value AS BINARY), 1, 4)
+  SUBSTR(CAST(src.value AS BINARY), 1, 4),
+  SUBSTR(CAST(src.value AS BINARY), 3),
+  SUBSTR(CAST(src.value AS BINARY), -4, 3)
 FROM src
 ORDER BY value
 LIMIT 100;

Modified: hive/trunk/ql/src/test/queries/clientpositive/udf_substr.q
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/udf_substr.q?rev=1291633&r1=1291632&r2=1291633&view=diff
==============================================================================
--- hive/trunk/ql/src/test/queries/clientpositive/udf_substr.q (original)
+++ hive/trunk/ql/src/test/queries/clientpositive/udf_substr.q Tue Feb 21 07:42:37 2012
@@ -47,3 +47,21 @@ SELECT
   substring('ABC', 1, 2147483647), substring('ABC', 2, 2147483647),
   substring('A', 0), substring('A', 1), substring('A', -1)
 FROM src LIMIT 1;
+
+-- test for binary substr
+SELECT
+  substr(null, 1), substr(null, 1, 1),
+  substr(ABC, null), substr(ABC, null, 1),
+  substr(ABC, 1, null),
+  substr(ABC, 0, 1), substr(ABC, 0, 2), substr(ABC, 0, 3), substr(ABC, 0, 4),
+  substr(ABC, 1, 1), substr(ABC, 1, 2), substr(ABC, 1, 3), substr(ABC, 1, 4),
+  substr(ABC, 2, 1), substr(ABC, 2, 2), substr(ABC, 2, 3), substr(ABC, 2, 4),
+  substr(ABC, 3, 1), substr(ABC, 3, 2), substr(ABC, 3, 3), substr(ABC, 3, 4),
+  substr(ABC, 4, 1),
+  substr(ABC, -1, 1), substr(ABC, -1, 2), substr(ABC, -1, 3), substr(ABC, -1, 4),
+  substr(ABC, -2, 1), substr(ABC, -2, 2), substr(ABC, -2, 3), substr(ABC, -2, 4),
+  substr(ABC, -3, 1), substr(ABC, -3, 2), substr(ABC, -3, 3), substr(ABC, -3, 4),
+  substr(ABC, -4, 1)
+FROM (
+   select CAST(concat(substr(value, 1, 0), 'ABC') as BINARY) as ABC from src LIMIT 1
+) X;

Modified: hive/trunk/ql/src/test/results/clientpositive/ba_table_udfs.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/ba_table_udfs.q.out?rev=1291633&r1=1291632&r2=1291633&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/ba_table_udfs.q.out (original)
+++ hive/trunk/ql/src/test/results/clientpositive/ba_table_udfs.q.out Tue Feb 21 07:42:37
2012
@@ -10,7 +10,9 @@ SELECT
   LENGTH(CAST(src.key AS BINARY)),
   LENGTH(CAST(src.value AS BINARY)),
   CONCAT(CAST(src.key AS BINARY), CAST(src.value AS BINARY)),
-  SUBSTR(CAST(src.value AS BINARY), 1, 4)
+  SUBSTR(CAST(src.value AS BINARY), 1, 4),
+  SUBSTR(CAST(src.value AS BINARY), 3),
+  SUBSTR(CAST(src.value AS BINARY), -4, 3)
 FROM src
 ORDER BY value
 LIMIT 100
@@ -25,110 +27,112 @@ SELECT
   LENGTH(CAST(src.key AS BINARY)),
   LENGTH(CAST(src.value AS BINARY)),
   CONCAT(CAST(src.key AS BINARY), CAST(src.value AS BINARY)),
-  SUBSTR(CAST(src.value AS BINARY), 1, 4)
+  SUBSTR(CAST(src.value AS BINARY), 1, 4),
+  SUBSTR(CAST(src.value AS BINARY), 3),
+  SUBSTR(CAST(src.value AS BINARY), -4, 3)
 FROM src
 ORDER BY value
 LIMIT 100
 POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src
 #### A masked pattern was here ####
-0	val_0	1	5	0val_0	al_0
-0	val_0	1	5	0val_0	al_0
-0	val_0	1	5	0val_0	al_0
-10	val_10	2	6	10val_10	al_1
-100	val_100	3	7	100val_100	al_1
-100	val_100	3	7	100val_100	al_1
-103	val_103	3	7	103val_103	al_1
-103	val_103	3	7	103val_103	al_1
-104	val_104	3	7	104val_104	al_1
-104	val_104	3	7	104val_104	al_1
-105	val_105	3	7	105val_105	al_1
-11	val_11	2	6	11val_11	al_1
-111	val_111	3	7	111val_111	al_1
-113	val_113	3	7	113val_113	al_1
-113	val_113	3	7	113val_113	al_1
-114	val_114	3	7	114val_114	al_1
-116	val_116	3	7	116val_116	al_1
-118	val_118	3	7	118val_118	al_1
-118	val_118	3	7	118val_118	al_1
-119	val_119	3	7	119val_119	al_1
-119	val_119	3	7	119val_119	al_1
-119	val_119	3	7	119val_119	al_1
-12	val_12	2	6	12val_12	al_1
-12	val_12	2	6	12val_12	al_1
-120	val_120	3	7	120val_120	al_1
-120	val_120	3	7	120val_120	al_1
-125	val_125	3	7	125val_125	al_1
-125	val_125	3	7	125val_125	al_1
-126	val_126	3	7	126val_126	al_1
-128	val_128	3	7	128val_128	al_1
-128	val_128	3	7	128val_128	al_1
-128	val_128	3	7	128val_128	al_1
-129	val_129	3	7	129val_129	al_1
-129	val_129	3	7	129val_129	al_1
-131	val_131	3	7	131val_131	al_1
-133	val_133	3	7	133val_133	al_1
-134	val_134	3	7	134val_134	al_1
-134	val_134	3	7	134val_134	al_1
-136	val_136	3	7	136val_136	al_1
-137	val_137	3	7	137val_137	al_1
-137	val_137	3	7	137val_137	al_1
-138	val_138	3	7	138val_138	al_1
-138	val_138	3	7	138val_138	al_1
-138	val_138	3	7	138val_138	al_1
-138	val_138	3	7	138val_138	al_1
-143	val_143	3	7	143val_143	al_1
-145	val_145	3	7	145val_145	al_1
-146	val_146	3	7	146val_146	al_1
-146	val_146	3	7	146val_146	al_1
-149	val_149	3	7	149val_149	al_1
-149	val_149	3	7	149val_149	al_1
-15	val_15	2	6	15val_15	al_1
-15	val_15	2	6	15val_15	al_1
-150	val_150	3	7	150val_150	al_1
-152	val_152	3	7	152val_152	al_1
-152	val_152	3	7	152val_152	al_1
-153	val_153	3	7	153val_153	al_1
-155	val_155	3	7	155val_155	al_1
-156	val_156	3	7	156val_156	al_1
-157	val_157	3	7	157val_157	al_1
-158	val_158	3	7	158val_158	al_1
-160	val_160	3	7	160val_160	al_1
-162	val_162	3	7	162val_162	al_1
-163	val_163	3	7	163val_163	al_1
-164	val_164	3	7	164val_164	al_1
-164	val_164	3	7	164val_164	al_1
-165	val_165	3	7	165val_165	al_1
-165	val_165	3	7	165val_165	al_1
-166	val_166	3	7	166val_166	al_1
-167	val_167	3	7	167val_167	al_1
-167	val_167	3	7	167val_167	al_1
-167	val_167	3	7	167val_167	al_1
-168	val_168	3	7	168val_168	al_1
-169	val_169	3	7	169val_169	al_1
-169	val_169	3	7	169val_169	al_1
-169	val_169	3	7	169val_169	al_1
-169	val_169	3	7	169val_169	al_1
-17	val_17	2	6	17val_17	al_1
-170	val_170	3	7	170val_170	al_1
-172	val_172	3	7	172val_172	al_1
-172	val_172	3	7	172val_172	al_1
-174	val_174	3	7	174val_174	al_1
-174	val_174	3	7	174val_174	al_1
-175	val_175	3	7	175val_175	al_1
-175	val_175	3	7	175val_175	al_1
-176	val_176	3	7	176val_176	al_1
-176	val_176	3	7	176val_176	al_1
-177	val_177	3	7	177val_177	al_1
-178	val_178	3	7	178val_178	al_1
-179	val_179	3	7	179val_179	al_1
-179	val_179	3	7	179val_179	al_1
-18	val_18	2	6	18val_18	al_1
-18	val_18	2	6	18val_18	al_1
-180	val_180	3	7	180val_180	al_1
-181	val_181	3	7	181val_181	al_1
-183	val_183	3	7	183val_183	al_1
-186	val_186	3	7	186val_186	al_1
-187	val_187	3	7	187val_187	al_1
-187	val_187	3	7	187val_187	al_1
-187	val_187	3	7	187val_187	al_1
+0	val_0	1	5	0val_0	val_	l_0	al_
+0	val_0	1	5	0val_0	val_	l_0	al_
+0	val_0	1	5	0val_0	val_	l_0	al_
+10	val_10	2	6	10val_10	val_	l_10	l_1
+100	val_100	3	7	100val_100	val_	l_100	_10
+100	val_100	3	7	100val_100	val_	l_100	_10
+103	val_103	3	7	103val_103	val_	l_103	_10
+103	val_103	3	7	103val_103	val_	l_103	_10
+104	val_104	3	7	104val_104	val_	l_104	_10
+104	val_104	3	7	104val_104	val_	l_104	_10
+105	val_105	3	7	105val_105	val_	l_105	_10
+11	val_11	2	6	11val_11	val_	l_11	l_1
+111	val_111	3	7	111val_111	val_	l_111	_11
+113	val_113	3	7	113val_113	val_	l_113	_11
+113	val_113	3	7	113val_113	val_	l_113	_11
+114	val_114	3	7	114val_114	val_	l_114	_11
+116	val_116	3	7	116val_116	val_	l_116	_11
+118	val_118	3	7	118val_118	val_	l_118	_11
+118	val_118	3	7	118val_118	val_	l_118	_11
+119	val_119	3	7	119val_119	val_	l_119	_11
+119	val_119	3	7	119val_119	val_	l_119	_11
+119	val_119	3	7	119val_119	val_	l_119	_11
+12	val_12	2	6	12val_12	val_	l_12	l_1
+12	val_12	2	6	12val_12	val_	l_12	l_1
+120	val_120	3	7	120val_120	val_	l_120	_12
+120	val_120	3	7	120val_120	val_	l_120	_12
+125	val_125	3	7	125val_125	val_	l_125	_12
+125	val_125	3	7	125val_125	val_	l_125	_12
+126	val_126	3	7	126val_126	val_	l_126	_12
+128	val_128	3	7	128val_128	val_	l_128	_12
+128	val_128	3	7	128val_128	val_	l_128	_12
+128	val_128	3	7	128val_128	val_	l_128	_12
+129	val_129	3	7	129val_129	val_	l_129	_12
+129	val_129	3	7	129val_129	val_	l_129	_12
+131	val_131	3	7	131val_131	val_	l_131	_13
+133	val_133	3	7	133val_133	val_	l_133	_13
+134	val_134	3	7	134val_134	val_	l_134	_13
+134	val_134	3	7	134val_134	val_	l_134	_13
+136	val_136	3	7	136val_136	val_	l_136	_13
+137	val_137	3	7	137val_137	val_	l_137	_13
+137	val_137	3	7	137val_137	val_	l_137	_13
+138	val_138	3	7	138val_138	val_	l_138	_13
+138	val_138	3	7	138val_138	val_	l_138	_13
+138	val_138	3	7	138val_138	val_	l_138	_13
+138	val_138	3	7	138val_138	val_	l_138	_13
+143	val_143	3	7	143val_143	val_	l_143	_14
+145	val_145	3	7	145val_145	val_	l_145	_14
+146	val_146	3	7	146val_146	val_	l_146	_14
+146	val_146	3	7	146val_146	val_	l_146	_14
+149	val_149	3	7	149val_149	val_	l_149	_14
+149	val_149	3	7	149val_149	val_	l_149	_14
+15	val_15	2	6	15val_15	val_	l_15	l_1
+15	val_15	2	6	15val_15	val_	l_15	l_1
+150	val_150	3	7	150val_150	val_	l_150	_15
+152	val_152	3	7	152val_152	val_	l_152	_15
+152	val_152	3	7	152val_152	val_	l_152	_15
+153	val_153	3	7	153val_153	val_	l_153	_15
+155	val_155	3	7	155val_155	val_	l_155	_15
+156	val_156	3	7	156val_156	val_	l_156	_15
+157	val_157	3	7	157val_157	val_	l_157	_15
+158	val_158	3	7	158val_158	val_	l_158	_15
+160	val_160	3	7	160val_160	val_	l_160	_16
+162	val_162	3	7	162val_162	val_	l_162	_16
+163	val_163	3	7	163val_163	val_	l_163	_16
+164	val_164	3	7	164val_164	val_	l_164	_16
+164	val_164	3	7	164val_164	val_	l_164	_16
+165	val_165	3	7	165val_165	val_	l_165	_16
+165	val_165	3	7	165val_165	val_	l_165	_16
+166	val_166	3	7	166val_166	val_	l_166	_16
+167	val_167	3	7	167val_167	val_	l_167	_16
+167	val_167	3	7	167val_167	val_	l_167	_16
+167	val_167	3	7	167val_167	val_	l_167	_16
+168	val_168	3	7	168val_168	val_	l_168	_16
+169	val_169	3	7	169val_169	val_	l_169	_16
+169	val_169	3	7	169val_169	val_	l_169	_16
+169	val_169	3	7	169val_169	val_	l_169	_16
+169	val_169	3	7	169val_169	val_	l_169	_16
+17	val_17	2	6	17val_17	val_	l_17	l_1
+170	val_170	3	7	170val_170	val_	l_170	_17
+172	val_172	3	7	172val_172	val_	l_172	_17
+172	val_172	3	7	172val_172	val_	l_172	_17
+174	val_174	3	7	174val_174	val_	l_174	_17
+174	val_174	3	7	174val_174	val_	l_174	_17
+175	val_175	3	7	175val_175	val_	l_175	_17
+175	val_175	3	7	175val_175	val_	l_175	_17
+176	val_176	3	7	176val_176	val_	l_176	_17
+176	val_176	3	7	176val_176	val_	l_176	_17
+177	val_177	3	7	177val_177	val_	l_177	_17
+178	val_178	3	7	178val_178	val_	l_178	_17
+179	val_179	3	7	179val_179	val_	l_179	_17
+179	val_179	3	7	179val_179	val_	l_179	_17
+18	val_18	2	6	18val_18	val_	l_18	l_1
+18	val_18	2	6	18val_18	val_	l_18	l_1
+180	val_180	3	7	180val_180	val_	l_180	_18
+181	val_181	3	7	181val_181	val_	l_181	_18
+183	val_183	3	7	183val_183	val_	l_183	_18
+186	val_186	3	7	186val_186	val_	l_186	_18
+187	val_187	3	7	187val_187	val_	l_187	_18
+187	val_187	3	7	187val_187	val_	l_187	_18
+187	val_187	3	7	187val_187	val_	l_187	_18

Modified: hive/trunk/ql/src/test/results/clientpositive/udf_substr.q.out
URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/udf_substr.q.out?rev=1291633&r1=1291632&r2=1291633&view=diff
==============================================================================
--- hive/trunk/ql/src/test/results/clientpositive/udf_substr.q.out (original)
+++ hive/trunk/ql/src/test/results/clientpositive/udf_substr.q.out Tue Feb 21 07:42:37 2012
@@ -141,3 +141,44 @@ POSTHOOK: type: QUERY
 POSTHOOK: Input: default@src
 #### A masked pattern was here ####
 CDEF	CDEF	CDEFG	CDEFG	ABC	ABC	BC	C	ABC	BC	A	A	A
+PREHOOK: query: -- test for binary substr
+SELECT
+  substr(null, 1), substr(null, 1, 1),
+  substr(ABC, null), substr(ABC, null, 1),
+  substr(ABC, 1, null),
+  substr(ABC, 0, 1), substr(ABC, 0, 2), substr(ABC, 0, 3), substr(ABC, 0, 4),
+  substr(ABC, 1, 1), substr(ABC, 1, 2), substr(ABC, 1, 3), substr(ABC, 1, 4),
+  substr(ABC, 2, 1), substr(ABC, 2, 2), substr(ABC, 2, 3), substr(ABC, 2, 4),
+  substr(ABC, 3, 1), substr(ABC, 3, 2), substr(ABC, 3, 3), substr(ABC, 3, 4),
+  substr(ABC, 4, 1),
+  substr(ABC, -1, 1), substr(ABC, -1, 2), substr(ABC, -1, 3), substr(ABC, -1, 4),
+  substr(ABC, -2, 1), substr(ABC, -2, 2), substr(ABC, -2, 3), substr(ABC, -2, 4),
+  substr(ABC, -3, 1), substr(ABC, -3, 2), substr(ABC, -3, 3), substr(ABC, -3, 4),
+  substr(ABC, -4, 1)
+FROM (
+   select CAST(concat(substr(value, 1, 0), 'ABC') as BINARY) as ABC from src LIMIT 1
+) X
+PREHOOK: type: QUERY
+PREHOOK: Input: default@src
+#### A masked pattern was here ####
+POSTHOOK: query: -- test for binary substr
+SELECT
+  substr(null, 1), substr(null, 1, 1),
+  substr(ABC, null), substr(ABC, null, 1),
+  substr(ABC, 1, null),
+  substr(ABC, 0, 1), substr(ABC, 0, 2), substr(ABC, 0, 3), substr(ABC, 0, 4),
+  substr(ABC, 1, 1), substr(ABC, 1, 2), substr(ABC, 1, 3), substr(ABC, 1, 4),
+  substr(ABC, 2, 1), substr(ABC, 2, 2), substr(ABC, 2, 3), substr(ABC, 2, 4),
+  substr(ABC, 3, 1), substr(ABC, 3, 2), substr(ABC, 3, 3), substr(ABC, 3, 4),
+  substr(ABC, 4, 1),
+  substr(ABC, -1, 1), substr(ABC, -1, 2), substr(ABC, -1, 3), substr(ABC, -1, 4),
+  substr(ABC, -2, 1), substr(ABC, -2, 2), substr(ABC, -2, 3), substr(ABC, -2, 4),
+  substr(ABC, -3, 1), substr(ABC, -3, 2), substr(ABC, -3, 3), substr(ABC, -3, 4),
+  substr(ABC, -4, 1)
+FROM (
+   select CAST(concat(substr(value, 1, 0), 'ABC') as BINARY) as ABC from src LIMIT 1
+) X
+POSTHOOK: type: QUERY
+POSTHOOK: Input: default@src
+#### A masked pattern was here ####
+NULL	NULL	null	null	null	A	AB	ABC	ABC	A	AB	ABC	ABC	B	BC	BC	BC	C	C	C	C		C	C	C	C	B	BC	BC	BC
A	AB	ABC	ABC	



Mime
View raw message