This is an automated email from the ASF dual-hosted git repository.

wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new d0284cb  ARROW-2236: [JS] Add more complete set of predicates
d0284cb is described below

commit d0284cb1857456f6ecbd1f4ae96eee8b3a259794
Author: Brian Hulette <[email protected]>
AuthorDate: Fri Mar 9 10:32:36 2018 -0500

    ARROW-2236: [JS] Add more complete set of predicates
    
    Adds not, gt, lt, and neq
    
    Author: Brian Hulette <[email protected]>
    
    Closes #1683 from TheNeuralBit/js-more-predicates and squashes the 
following commits:
    
    707de827 <Brian Hulette> Use two letter names
    56ecea38 <Brian Hulette> export packBools, import compiled code in 
vector-test
    32b26e3b <Brian Hulette> lint
    57383277 <Brian Hulette> add externs
    84895a00 <Brian Hulette> Add not, lt, gt, neq
---
 js/src/Arrow.externs.js      | 15 +++++++++++++--
 js/src/Arrow.ts              | 27 +++++++++++++++------------
 js/src/predicate.ts          | 25 +++++++++++++++++++++++--
 js/test/unit/table-tests.ts  | 38 +++++++++++++++++++++++++++-----------
 js/test/unit/vector-tests.ts | 10 +++++-----
 5 files changed, 83 insertions(+), 32 deletions(-)

diff --git a/js/src/Arrow.externs.js b/js/src/Arrow.externs.js
index a14f959..4932c67 100644
--- a/js/src/Arrow.externs.js
+++ b/js/src/Arrow.externs.js
@@ -74,17 +74,24 @@ var custom = function () {};
 
 var Value = function() {};
 /** @type {?} */
-Value.prototype.gteq;
+Value.prototype.ge;
 /** @type {?} */
-Value.prototype.lteq;
+Value.prototype.le;
 /** @type {?} */
 Value.prototype.eq;
+/** @type {?} */
+Value.prototype.lt;
+/** @type {?} */
+Value.prototype.gt;
+/** @type {?} */
+Value.prototype.ne;
 
 var Col = function() {};
 /** @type {?} */
 Col.prototype.bind;
 var Or = function() {};
 var And = function() {};
+var Not = function() {};
 var GTeq = function () {};
 /** @type {?} */
 GTeq.prototype.and;
@@ -108,6 +115,8 @@ Predicate.prototype.and;
 /** @type {?} */
 Predicate.prototype.or;
 /** @type {?} */
+Predicate.prototype.not;
+/** @type {?} */
 Predicate.prototype.ands;
 var Literal = function() {};
 
@@ -209,6 +218,8 @@ Int128.prototype.plus
 /** @type {?} */
 Int128.prototype.hex
 
+var packBools = function() {};
+
 var Type = function() {};
 /** @type {?} */
 Type.NONE = function() {};
diff --git a/js/src/Arrow.ts b/js/src/Arrow.ts
index 4a0a2ac..23e8b99 100644
--- a/js/src/Arrow.ts
+++ b/js/src/Arrow.ts
@@ -18,7 +18,8 @@
 import * as type_ from './type';
 import * as data_ from './data';
 import * as vector_ from './vector';
-import * as util_ from './util/int';
+import * as util_int_ from './util/int';
+import * as util_bit_ from './util/bit';
 import * as visitor_ from './visitor';
 import * as view_ from './vector/view';
 import * as predicate_ from './predicate';
@@ -40,9 +41,10 @@ export { Table, DataFrame, NextFunc, BindFunc, CountByResult 
};
 export { Field, Schema, RecordBatch, Vector, Type };
 
 export namespace util {
-    export import Uint64 = util_.Uint64;
-    export import Int64 = util_.Int64;
-    export import Int128 = util_.Int128;
+    export import Uint64 = util_int_.Uint64;
+    export import Int64 = util_int_.Int64;
+    export import Int128 = util_int_.Int128;
+    export import packBools = util_bit_.packBools;
 }
 
 export namespace data {
@@ -173,6 +175,7 @@ export namespace predicate {
     export import Or = predicate_.Or;
     export import Col = predicate_.Col;
     export import And = predicate_.And;
+    export import Not = predicate_.Not;
     export import GTeq = predicate_.GTeq;
     export import LTeq = predicate_.LTeq;
     export import Value = predicate_.Value;
@@ -222,16 +225,16 @@ Table['empty'] = Table.empty;
 Vector['create'] = Vector.create;
 RecordBatch['from'] = RecordBatch.from;
 
-util_.Uint64['add'] = util_.Uint64.add;
-util_.Uint64['multiply'] = util_.Uint64.multiply;
+util_int_.Uint64['add'] = util_int_.Uint64.add;
+util_int_.Uint64['multiply'] = util_int_.Uint64.multiply;
 
-util_.Int64['add'] = util_.Int64.add;
-util_.Int64['multiply'] = util_.Int64.multiply;
-util_.Int64['fromString'] = util_.Int64.fromString;
+util_int_.Int64['add'] = util_int_.Int64.add;
+util_int_.Int64['multiply'] = util_int_.Int64.multiply;
+util_int_.Int64['fromString'] = util_int_.Int64.fromString;
 
-util_.Int128['add'] = util_.Int128.add;
-util_.Int128['multiply'] = util_.Int128.multiply;
-util_.Int128['fromString'] = util_.Int128.fromString;
+util_int_.Int128['add'] = util_int_.Int128.add;
+util_int_.Int128['multiply'] = util_int_.Int128.multiply;
+util_int_.Int128['fromString'] = util_int_.Int128.fromString;
 
 data_.ChunkedData['computeOffsets'] = data_.ChunkedData.computeOffsets;
 
diff --git a/js/src/predicate.ts b/js/src/predicate.ts
index b177b4f..bff3938 100644
--- a/js/src/predicate.ts
+++ b/js/src/predicate.ts
@@ -26,14 +26,23 @@ export abstract class Value<T> {
         if (!(other instanceof Value)) { other = new Literal(other); }
         return new Equals(this, other);
     }
-    lteq(other: Value<T> | T): Predicate {
+    le(other: Value<T> | T): Predicate {
         if (!(other instanceof Value)) { other = new Literal(other); }
         return new LTeq(this, other);
     }
-    gteq(other: Value<T> | T): Predicate {
+    ge(other: Value<T> | T): Predicate {
         if (!(other instanceof Value)) { other = new Literal(other); }
         return new GTeq(this, other);
     }
+    lt(other: Value<T> | T): Predicate {
+        return new Not(this.ge(other));
+    }
+    gt(other: Value<T> | T): Predicate {
+        return new Not(this.le(other));
+    }
+    ne(other: Value<T> | T): Predicate {
+        return new Not(this.eq(other));
+    }
 }
 
 export class Literal<T= any> extends Value<T> {
@@ -70,6 +79,7 @@ export abstract class Predicate {
     abstract bind(batch: RecordBatch): PredicateFunc;
     and(expr: Predicate): Predicate { return new And(this, expr); }
     or(expr: Predicate): Predicate { return new Or(this, expr); }
+    not(): Predicate { return new Not(this); }
     ands(): Predicate[] { return [this]; }
 }
 
@@ -222,6 +232,17 @@ export class GTeq extends ComparisonPredicate {
     }
 }
 
+export class Not extends Predicate {
+    constructor(public readonly child: Predicate) {
+        super();
+    }
+
+    bind(batch: RecordBatch) {
+        const func = this.child.bind(batch);
+        return (idx: number, batch: RecordBatch) => !func(idx, batch);
+    }
+}
+
 export class CustomPredicate extends Predicate {
     constructor(private next: PredicateFunc, private bind_: (batch: 
RecordBatch) => void) {
         super();
diff --git a/js/test/unit/table-tests.ts b/js/test/unit/table-tests.ts
index 8a43381..37bbf62 100644
--- a/js/test/unit/table-tests.ts
+++ b/js/test/unit/table-tests.ts
@@ -327,27 +327,39 @@ describe(`Table`, () => {
             const filter_tests = [
                 {
                     name:     `filter on f32 >= 0`,
-                    filtered: table.filter(col('f32').gteq(0)),
+                    filtered: table.filter(col('f32').ge(0)),
                     expected: values.filter((row) => row[F32] >= 0)
                 }, {
                     name:     `filter on 0 <= f32`,
-                    filtered: table.filter(lit(0).lteq(col('f32'))),
+                    filtered: table.filter(lit(0).le(col('f32'))),
                     expected: values.filter((row) => 0 <= row[F32])
                 }, {
                     name:     `filter on i32 <= 0`,
-                    filtered: table.filter(col('i32').lteq(0)),
+                    filtered: table.filter(col('i32').le(0)),
                     expected: values.filter((row) => row[I32] <= 0)
                 }, {
                     name:     `filter on 0 >= i32`,
-                    filtered: table.filter(lit(0).gteq(col('i32'))),
+                    filtered: table.filter(lit(0).ge(col('i32'))),
                     expected: values.filter((row) => 0 >= row[I32])
                 }, {
+                    name:     `filter on f32 < 0`,
+                    filtered: table.filter(col('f32').lt(0)),
+                    expected: values.filter((row) => row[F32] < 0)
+                }, {
+                    name:     `filter on i32 > 1 (empty)`,
+                    filtered: table.filter(col('i32').gt(0)),
+                    expected: values.filter((row) => row[I32] > 0)
+                }, {
                     name:     `filter on f32 <= -.25 || f3 >= .25`,
-                    filtered: 
table.filter(col('f32').lteq(-.25).or(col('f32').gteq(.25))),
+                    filtered: 
table.filter(col('f32').le(-.25).or(col('f32').ge(.25))),
                     expected: values.filter((row) => row[F32] <= -.25 || 
row[F32] >= .25)
                 }, {
+                    name:     `filter on !(f32 <= -.25 || f3 >= .25) (not)`,
+                    filtered: 
table.filter(col('f32').le(-.25).or(col('f32').ge(.25)).not()),
+                    expected: values.filter((row) => !(row[F32] <= -.25 || 
row[F32] >= .25))
+                }, {
                     name:     `filter method combines predicates (f32 >= 0 && 
i32 <= 0)`,
-                    filtered: 
table.filter(col('i32').lteq(0)).filter(col('f32').gteq(0)),
+                    filtered: 
table.filter(col('i32').le(0)).filter(col('f32').ge(0)),
                     expected: values.filter((row) => row[I32] <= 0 && row[F32] 
>= 0)
                 }, {
                     name:     `filter on dictionary == 'a'`,
@@ -358,12 +370,16 @@ describe(`Table`, () => {
                     filtered: table.filter(lit('a').eq(col('dictionary'))),
                     expected: values.filter((row) => row[DICT] === 'a')
                 }, {
+                    name:     `filter on dictionary != 'b'`,
+                    filtered: table.filter(col('dictionary').ne('b')),
+                    expected: values.filter((row) => row[DICT] !== 'b')
+                }, {
                     name:     `filter on f32 >= i32`,
-                    filtered: table.filter(col('f32').gteq(col('i32'))),
+                    filtered: table.filter(col('f32').ge(col('i32'))),
                     expected: values.filter((row) => row[F32] >= row[I32])
                 }, {
                     name:     `filter on f32 <= i32`,
-                    filtered: table.filter(col('f32').lteq(col('i32'))),
+                    filtered: table.filter(col('f32').le(col('i32'))),
                     expected: values.filter((row) => row[F32] <= row[I32])
                 }, {
                     name:     `filter on f32*i32 > 0 (custom predicate)`,
@@ -455,17 +471,17 @@ describe(`Table`, () => {
                 expect(selected.toString()).toEqual(expected);
             });
             test(`table.filter(..).count() on always false predicates returns 
0`, () => {
-                expect(table.filter(col('i32').gteq(100)).count()).toEqual(0);
+                expect(table.filter(col('i32').ge(100)).count()).toEqual(0);
                 
expect(table.filter(col('dictionary').eq('z')).count()).toEqual(0);
             });
             describe(`lit-lit comparison`, () => {
                 test(`always-false count() returns 0`, () => {
                     
expect(table.filter(lit('abc').eq('def')).count()).toEqual(0);
-                    expect(table.filter(lit(0).gteq(1)).count()).toEqual(0);
+                    expect(table.filter(lit(0).ge(1)).count()).toEqual(0);
                 });
                 test(`always-true count() returns length`, () => {
                     
expect(table.filter(lit('abc').eq('abc')).count()).toEqual(table.length);
-                    
expect(table.filter(lit(-100).lteq(0)).count()).toEqual(table.length);
+                    
expect(table.filter(lit(-100).le(0)).count()).toEqual(table.length);
                 });
             });
             describe(`col-col comparison`, () => {
diff --git a/js/test/unit/vector-tests.ts b/js/test/unit/vector-tests.ts
index 3eb3fbe..d25e0e9 100644
--- a/js/test/unit/vector-tests.ts
+++ b/js/test/unit/vector-tests.ts
@@ -17,13 +17,13 @@
 
 import { TextEncoder } from 'text-encoding-utf-8';
 import Arrow from '../Arrow';
-import { type, TypedArray, TypedArrayConstructor, Vector } from 
'../../src/Arrow';
-import { packBools } from '../../src/util/bit'
+import { TypedArray, TypedArrayConstructor } from '../../src/Arrow';
 
 const utf8Encoder = new TextEncoder('utf-8');
 
+const { packBools } = Arrow.util;
 const { BoolData, FlatData, FlatListData, DictionaryData } = Arrow.data;
-const { IntVector, FloatVector, BoolVector, Utf8Vector, DictionaryVector } = 
Arrow.vector;
+const { Vector, IntVector, FloatVector, BoolVector, Utf8Vector, 
DictionaryVector } = Arrow.vector;
 const {
     Dictionary, Utf8, Bool,
     Float16, Float32, Float64,
@@ -143,7 +143,7 @@ describe('Float16Vector', () => {
     const values = concatTyped(Uint16Array, ...bytes);
     const vector = bytes
         .map((b) => new Uint16Array(b.buffer))
-        .map((b) => new FloatVector<type.Float16>(new FlatData(new Float16(), 
b.length, null, b)))
+        .map((b) => new FloatVector<Float16>(new FlatData(new Float16(), 
b.length, null, b)))
         .reduce((v: any, v2) => v.concat(v2));
     const n = values.length;
     const clamp = (x: number) => (x -  32767) / 32767;
@@ -336,7 +336,7 @@ describe(`DictionaryVector`, () => {
 
         describe(`sliced`, () => {
             basicVectorTests(vector.slice(10, 20), values.slice(10,20), 
extras);
-        })
+        });
     });
 
     describe(`index with nullCount > 0`, () => {

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to