Explorar o código

HPCC-13826 Extension of index_field[1..n]=field to IN

Signed-off-by: Shamser Ahmed <shamser.ahmed@lexisnexis.co.uk>
Shamser Ahmed %!s(int64=9) %!d(string=hai) anos
pai
achega
eccb729f11

+ 47 - 4
ecl/hqlcpp/hqlsource.cpp

@@ -4015,12 +4015,27 @@ void MonitorExtractor::buildKeySegmentInExpr(BuildMonitorState & buildState, Key
             if (compare)
                 translator.buildFilter(subctx, compare);
 
-            OwnedHqlExpr address = getMonitorValueAddress(subctx, normalized);
-
             HqlExprArray args;
             args.append(*LINK(targetVar));
-            args.append(*LINK(address));
-            args.append(*LINK(address));
+            unsigned srcSize = normalized->queryType()->getSize();
+            if (srcSize < curSize)
+            {
+                OwnedHqlExpr lengthExpr = getSizetConstant(srcSize);
+                OwnedHqlExpr rangeLower = getRangeLimit(fieldType, lengthExpr, normalized, -1);
+                OwnedHqlExpr rangeUpper = getRangeLimit(fieldType, lengthExpr, normalized, +1);
+
+                CHqlBoundExpr boundLower, boundUpper;
+                translator.buildExpr(subctx, rangeLower, boundLower);
+                translator.buildExpr(subctx, rangeUpper, boundUpper);
+                args.append(*getPointer(boundLower.expr));
+                args.append(*getPointer(boundUpper.expr));
+            }
+            else
+            {
+                OwnedHqlExpr address = getMonitorValueAddress(subctx, normalized);
+                args.append(*LINK(address));
+                args.append(*LINK(address));
+            }
             translator.callProcedure(subctx, func, args);
         }
     }
@@ -5005,6 +5020,7 @@ IHqlExpression * MonitorExtractor::castToFieldAndBack(IHqlExpression * left, IHq
                 return LINK(right);
             return ensureExprType(right, leftType);
         }
+    case no_substring:
     case no_add:
     case no_sub:
         return castToFieldAndBack(left->queryChild(0), right);
@@ -5051,6 +5067,12 @@ IHqlExpression * MonitorExtractor::invertTransforms(IHqlExpression * left, IHqlE
             OwnedHqlExpr adjusted = createValue(op == no_sub ? no_add : no_sub, right->getType(), LINK(right), LINK(left->queryChild(1)));
             return invertTransforms(left->queryChild(0), adjusted);
         }
+     case no_substring:
+         {
+             assertex(right->getOperator() != no_list);
+
+             return invertTransforms(left->queryChild(0), right);
+         }
     default:
         UNIMPLEMENTED;
     }
@@ -5138,6 +5160,27 @@ IHqlExpression * MonitorExtractor::isKeyableFilter(IHqlExpression * left, IHqlEx
             reason.set(KFRnokey);
         return NULL;
 
+    case no_substring:
+        {
+            IHqlExpression * range = left->queryChild(1);
+            if (range->getOperator() == no_rangeto)
+            {
+                IValue *end = range->queryChild(0)->queryValue();
+                if (!end)
+                    break;
+                return isKeyableFilter(left->queryChild(0), right, duplicate, compareOp, reason, keyedKind);
+            }
+            else if (range->getOperator() == no_range)
+            {
+                IValue *start = range->queryChild(0)->queryValue();
+                IValue *end = range->queryChild(1)->queryValue();
+                if (!start || !end || start->getIntValue() != 1)
+                    break;
+                return isKeyableFilter(left->queryChild(0), right, duplicate, compareOp, reason, keyedKind);
+            }
+            reason.set(KFRtoocomplex, right);
+            return NULL;
+        }
     case no_add:
     case no_sub:
         if (isIndexInvariant(left->queryChild(1)))

+ 80 - 0
testing/regress/ecl/indexsubstring.ecl

@@ -0,0 +1,80 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2016 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.
+############################################################################## */
+
+//version multiPart=false
+
+import ^ as root;
+multiPart := #IFDEFINED(root.multiPart, false);
+
+//--- end of version configuration ---
+
+postcodes := DATASET([{'KT19 1AA'}, {'KT19 1AB'}, {'KT19 1AC'}, {'KT19 1AD'},
+                      {'KT20 1AE'}, {'KT20 1AF'}, {'KT20 1AG'}, {'KT20 1AH'},
+                      {'KT21 1AI'}, {'KT21 1AJ'}, {'KT21 1AK'}, {'KT21 1AL'},
+                      {'KT22 1AM'}, {'KT22 1AN'}, {'KT22 1AO'}, {'KT22 1AA'},
+                      {'KT23 1AB'}, {'KT23 1AC'}, {'KT23 1AD'}, {'KT23 1AE'},
+                      {'KT30 1AF'}, {'KT30 1AG'}, {'KT30 1AH'}, {'KT30 1AI'},
+                      {'KT31 1AJ'}, {'KT31 1AK'}, {'KT31 1AL'}, {'KT31 1AM'},
+                      {'KT32 1AN'}, {'KT32 1AO'}, {'KT32 1AA'}, {'KT32 1AB'},
+                      {'KT40 1AC'}, {'KT40 1AD'}, {'KT40 1AE'}, {'KT40 1AF'},
+                      {'KT41 1AG'}, {'KT41 1AH'}, {'KT41 1AI'}, {'KT41 1AJ'},
+                      {'KT41 1AK'}, {'KT41 1AL'}, {'KT41 1AM'}, {'KT41 1AN'},
+                      {'KT50 2AB'}, {'KT50 3DE'}, {'KT50 4FG'}, {'KT50 5HI'},
+                      {'KT60 2AB'}, {'KT60 3DE'}, {'KT60 4FG'}, {'KT60 5HI'},
+                      {'KT3'}, {'KT4'},{'KT50'}], {string8 postcode});
+
+outputraw := OUTPUT(postcodes,,'TST::postcodes', OVERWRITE);
+
+
+Rawfile := DATASET('TST::postcodes', { string8 postcode, UNSIGNED8
+                                      __filepos {virtual(fileposition)}}, FLAT);
+
+INDX_Postcode := INDEX(Rawfile, {postcode, __filepos}, 'TST::postcode.key');
+BuildIndexOp := BUILDINDEX(INDX_Postcode, OVERWRITE);
+
+SET OF STRING4 PartialPostcode:= ['KT19','KT40','KT3 ','KT20 1AEEE','KT50','KT60 3DE'];
+SET OF STRING4 PartialPostcodeStored:= ['KT19','KT40','KT3 ','KT20 1AEEE', 'KT50','KT60 3DE']:stored('PartialPostcode');
+SET OF STRING PartialPostcodeStored2:= ['KT19','KT40','KT3 ','KT20 1AEEE', 'KT50','KT60 3DE']:stored('PartialPostcode2');
+
+partialmatch1 := INDX_Postcode( KEYED(postcode[1..4] IN PartialPostcode) );
+partialmatch2 := INDX_Postcode( KEYED(postcode[1..4] IN PartialPostcodeStored) );
+partialmatch3 := INDX_Postcode( KEYED(postcode[..4] IN PartialPostcodeStored) );
+partialmatch4 := INDX_Postcode( KEYED(postcode[..4] IN PartialPostcodestored2) );
+fullmatch1 := INDX_Postcode( KEYED(postcode IN PartialPostcodeStored) );
+fullmatch2 := INDX_Postcode( KEYED(postcode IN PartialPostcodeStored2) );
+
+four := 4 : stored('four');
+
+partialmatch5 := INDX_Postcode( postcode[1..four] IN PartialPostcode );
+partialmatch6 := INDX_Postcode( postcode[1..four] IN PartialPostcodeStored );
+partialmatch7 := INDX_Postcode( postcode[..four] IN PartialPostcodeStored );
+partialmatch8 := INDX_Postcode( postcode[..four] IN PartialPostcodestored2 );
+
+SEQUENTIAL(
+  outputraw,
+  BuildIndexOp,
+  OUTPUT(partialmatch1),  // match KT19*, KT40*, KT3, KT20*, KT50* and KT60*
+  OUTPUT(partialmatch2),  // match KT19*, KT40*, KT3, KT20*, KT50* and KT60*
+  OUTPUT(partialmatch3),  // match KT19*, KT40*, KT3, KT20*, KT50* and KT60*
+  OUTPUT(partialmatch4),  // match KT19*, KT40*, KT3 and KT50*
+  OUTPUT(fullmatch1),     // match KT3 and KT50
+  OUTPUT(fullmatch2),     // match KT3, KT50 and KT60 3DE
+  OUTPUT(partialmatch5),  // match KT19*, KT40*, KT3, KT20*, KT50* and KT60*
+  OUTPUT(partialmatch6),  // match KT19*, KT40*, KT3, KT20*, KT50* and KT60*
+  OUTPUT(partialmatch7),  // match KT19*, KT40*, KT3, KT20*, KT50* and KT60*
+  OUTPUT(partialmatch8),  // match KT19*, KT40*, KT3 and KT50*
+);

+ 189 - 0
testing/regress/ecl/key/indexsubstring.xml

@@ -0,0 +1,189 @@
+<Dataset name='Result 1'>
+</Dataset>
+<Dataset name='Result 2'>
+</Dataset>
+<Dataset name='Result 3'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT20 1AE</postcode><__filepos>32</__filepos></Row>
+ <Row><postcode>KT20 1AF</postcode><__filepos>40</__filepos></Row>
+ <Row><postcode>KT20 1AG</postcode><__filepos>48</__filepos></Row>
+ <Row><postcode>KT20 1AH</postcode><__filepos>56</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+ <Row><postcode>KT60 2AB</postcode><__filepos>384</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+ <Row><postcode>KT60 4FG</postcode><__filepos>400</__filepos></Row>
+ <Row><postcode>KT60 5HI</postcode><__filepos>408</__filepos></Row>
+</Dataset>
+<Dataset name='Result 4'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT20 1AE</postcode><__filepos>32</__filepos></Row>
+ <Row><postcode>KT20 1AF</postcode><__filepos>40</__filepos></Row>
+ <Row><postcode>KT20 1AG</postcode><__filepos>48</__filepos></Row>
+ <Row><postcode>KT20 1AH</postcode><__filepos>56</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+ <Row><postcode>KT60 2AB</postcode><__filepos>384</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+ <Row><postcode>KT60 4FG</postcode><__filepos>400</__filepos></Row>
+ <Row><postcode>KT60 5HI</postcode><__filepos>408</__filepos></Row>
+</Dataset>
+<Dataset name='Result 5'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT20 1AE</postcode><__filepos>32</__filepos></Row>
+ <Row><postcode>KT20 1AF</postcode><__filepos>40</__filepos></Row>
+ <Row><postcode>KT20 1AG</postcode><__filepos>48</__filepos></Row>
+ <Row><postcode>KT20 1AH</postcode><__filepos>56</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+ <Row><postcode>KT60 2AB</postcode><__filepos>384</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+ <Row><postcode>KT60 4FG</postcode><__filepos>400</__filepos></Row>
+ <Row><postcode>KT60 5HI</postcode><__filepos>408</__filepos></Row>
+</Dataset>
+<Dataset name='Result 6'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+</Dataset>
+<Dataset name='Result 7'>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+</Dataset>
+<Dataset name='Result 8'>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+</Dataset>
+<Dataset name='Result 9'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT20 1AE</postcode><__filepos>32</__filepos></Row>
+ <Row><postcode>KT20 1AF</postcode><__filepos>40</__filepos></Row>
+ <Row><postcode>KT20 1AG</postcode><__filepos>48</__filepos></Row>
+ <Row><postcode>KT20 1AH</postcode><__filepos>56</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+ <Row><postcode>KT60 2AB</postcode><__filepos>384</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+ <Row><postcode>KT60 4FG</postcode><__filepos>400</__filepos></Row>
+ <Row><postcode>KT60 5HI</postcode><__filepos>408</__filepos></Row>
+</Dataset>
+<Dataset name='Result 10'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT20 1AE</postcode><__filepos>32</__filepos></Row>
+ <Row><postcode>KT20 1AF</postcode><__filepos>40</__filepos></Row>
+ <Row><postcode>KT20 1AG</postcode><__filepos>48</__filepos></Row>
+ <Row><postcode>KT20 1AH</postcode><__filepos>56</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+ <Row><postcode>KT60 2AB</postcode><__filepos>384</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+ <Row><postcode>KT60 4FG</postcode><__filepos>400</__filepos></Row>
+ <Row><postcode>KT60 5HI</postcode><__filepos>408</__filepos></Row>
+</Dataset>
+<Dataset name='Result 11'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT20 1AE</postcode><__filepos>32</__filepos></Row>
+ <Row><postcode>KT20 1AF</postcode><__filepos>40</__filepos></Row>
+ <Row><postcode>KT20 1AG</postcode><__filepos>48</__filepos></Row>
+ <Row><postcode>KT20 1AH</postcode><__filepos>56</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+ <Row><postcode>KT60 2AB</postcode><__filepos>384</__filepos></Row>
+ <Row><postcode>KT60 3DE</postcode><__filepos>392</__filepos></Row>
+ <Row><postcode>KT60 4FG</postcode><__filepos>400</__filepos></Row>
+ <Row><postcode>KT60 5HI</postcode><__filepos>408</__filepos></Row>
+</Dataset>
+<Dataset name='Result 12'>
+ <Row><postcode>KT19 1AA</postcode><__filepos>0</__filepos></Row>
+ <Row><postcode>KT19 1AB</postcode><__filepos>8</__filepos></Row>
+ <Row><postcode>KT19 1AC</postcode><__filepos>16</__filepos></Row>
+ <Row><postcode>KT19 1AD</postcode><__filepos>24</__filepos></Row>
+ <Row><postcode>KT3     </postcode><__filepos>416</__filepos></Row>
+ <Row><postcode>KT40 1AC</postcode><__filepos>256</__filepos></Row>
+ <Row><postcode>KT40 1AD</postcode><__filepos>264</__filepos></Row>
+ <Row><postcode>KT40 1AE</postcode><__filepos>272</__filepos></Row>
+ <Row><postcode>KT40 1AF</postcode><__filepos>280</__filepos></Row>
+ <Row><postcode>KT50    </postcode><__filepos>432</__filepos></Row>
+ <Row><postcode>KT50 2AB</postcode><__filepos>352</__filepos></Row>
+ <Row><postcode>KT50 3DE</postcode><__filepos>360</__filepos></Row>
+ <Row><postcode>KT50 4FG</postcode><__filepos>368</__filepos></Row>
+ <Row><postcode>KT50 5HI</postcode><__filepos>376</__filepos></Row>
+</Dataset>