Skip to content

Commit

Permalink
GH-39017: [JS] Add typeId as attribute (#39018)
Browse files Browse the repository at this point in the history
### Rationale for this change

Support reconstructing `DataType` after `postMessage`.

### What changes are included in this PR?

Make `typeId` an attribute, not a getter.

### Are these changes tested?

Passes all existing tests.

<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code

If tests are not included in your PR, please explain why (for example,
are they covered by existing tests)?
-->

### Are there any user-facing changes?

No

<!--
If there are user-facing changes then we may require documentation to be
updated before approving the PR.
-->

<!--
If there are any breaking changes to public APIs, please uncomment the
line below and explain which changes are breaking.
-->
<!-- **This PR includes breaking changes to public APIs.** -->

<!--
Please uncomment the line below (and provide explanation) if the changes
fix either (a) a security vulnerability, (b) a bug that caused incorrect
or invalid data to be produced, or (c) a bug that causes a crash (even
when the API contract is upheld). We use this to highlight fixes to
issues that may affect users without their knowledge. For this reason,
fixing bugs that cause errors don't count, since those are usually
obvious.
-->
<!-- **This PR contains a "Critical Fix".** -->
* Closes: #39017
  • Loading branch information
kylebarron authored Dec 25, 2023
1 parent ec41209 commit 90f7eca
Showing 1 changed file with 28 additions and 42 deletions.
70 changes: 28 additions & 42 deletions js/src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ export abstract class DataType<TType extends Type = Type, TChildren extends Type
/** @nocollapse */ static isDenseUnion(x: any): x is DenseUnion { return DataType.isUnion(x) && x.mode === UnionMode.Dense; }
/** @nocollapse */ static isSparseUnion(x: any): x is SparseUnion { return DataType.isUnion(x) && x.mode === UnionMode.Sparse; }

public get typeId(): TType { return <any>Type.NONE; }
declare public readonly typeId: TType;

constructor(typeId: TType) {
this.typeId = typeId;
}

protected static [Symbol.toStringTag] = ((proto: DataType) => {
(<any>proto).children = null;
Expand All @@ -93,8 +97,10 @@ export abstract class DataType<TType extends Type = Type, TChildren extends Type
export interface Null extends DataType<Type.Null> { TArray: void; TValue: null }
/** @ignore */
export class Null extends DataType<Type.Null> {
constructor() {
super(Type.Null);
}
public toString() { return `Null`; }
public get typeId() { return Type.Null as Type.Null; }
protected static [Symbol.toStringTag] = ((proto: Null) => proto[Symbol.toStringTag] = 'Null')(Null.prototype);
}

Expand All @@ -119,9 +125,8 @@ interface Int_<T extends Ints = Ints> extends DataType<T> { TArray: IType[T]['TA
class Int_<T extends Ints = Ints> extends DataType<T> {
constructor(public readonly isSigned: IType[T]['isSigned'],
public readonly bitWidth: IType[T]['bitWidth']) {
super();
super(Type.Int as T);
}
public get typeId() { return Type.Int as T; }
public get ArrayType() {
switch (this.bitWidth) {
case 8: return this.isSigned ? Int8Array : Uint8Array;
Expand Down Expand Up @@ -206,9 +211,8 @@ export interface Float<T extends Floats = Floats> extends DataType<T> { TArray:
/** @ignore */
export class Float<T extends Floats = Floats> extends DataType<T> {
constructor(public readonly precision: Precision) {
super();
super(Type.Float as T);
}
public get typeId() { return Type.Float as T; }
public get ArrayType(): TypedArrayConstructor<FType[T]['TArray']> {
switch (this.precision) {
case Precision.HALF: return Uint16Array;
Expand Down Expand Up @@ -241,9 +245,8 @@ export interface Binary extends DataType<Type.Binary> { TArray: Uint8Array; TOff
/** @ignore */
export class Binary extends DataType<Type.Binary> {
constructor() {
super();
super(Type.Binary);
}
public get typeId() { return Type.Binary as Type.Binary; }
public toString() { return `Binary`; }
protected static [Symbol.toStringTag] = ((proto: Binary) => {
(<any>proto).ArrayType = Uint8Array;
Expand All @@ -256,9 +259,8 @@ export interface LargeBinary extends DataType<Type.LargeBinary> { TArray: Uint8A
/** @ignore */
export class LargeBinary extends DataType<Type.LargeBinary> {
constructor() {
super();
super(Type.LargeBinary);
}
public get typeId() { return Type.LargeBinary as Type.LargeBinary; }
public toString() { return `LargeBinary`; }
protected static [Symbol.toStringTag] = ((proto: LargeBinary) => {
(<any>proto).ArrayType = Uint8Array;
Expand All @@ -272,9 +274,8 @@ export interface Utf8 extends DataType<Type.Utf8> { TArray: Uint8Array; TOffsetA
/** @ignore */
export class Utf8 extends DataType<Type.Utf8> {
constructor() {
super();
super(Type.Utf8);
}
public get typeId() { return Type.Utf8 as Type.Utf8; }
public toString() { return `Utf8`; }
protected static [Symbol.toStringTag] = ((proto: Utf8) => {
(<any>proto).ArrayType = Uint8Array;
Expand All @@ -287,9 +288,8 @@ export interface LargeUtf8 extends DataType<Type.LargeUtf8> { TArray: Uint8Array
/** @ignore */
export class LargeUtf8 extends DataType<Type.LargeUtf8> {
constructor() {
super();
super(Type.LargeUtf8);
}
public get typeId() { return Type.LargeUtf8 as Type.LargeUtf8; }
public toString() { return `LargeUtf8`; }
protected static [Symbol.toStringTag] = ((proto: LargeUtf8) => {
(<any>proto).ArrayType = Uint8Array;
Expand All @@ -303,9 +303,8 @@ export interface Bool extends DataType<Type.Bool> { TArray: Uint8Array; TValue:
/** @ignore */
export class Bool extends DataType<Type.Bool> {
constructor() {
super();
super(Type.Bool);
}
public get typeId() { return Type.Bool as Type.Bool; }
public toString() { return `Bool`; }
protected static [Symbol.toStringTag] = ((proto: Bool) => {
(<any>proto).ArrayType = Uint8Array;
Expand All @@ -320,9 +319,8 @@ export class Decimal extends DataType<Type.Decimal> {
constructor(public readonly scale: number,
public readonly precision: number,
public readonly bitWidth: number = 128) {
super();
super(Type.Decimal);
}
public get typeId() { return Type.Decimal as Type.Decimal; }
public toString() { return `Decimal[${this.precision}e${this.scale > 0 ? `+` : ``}${this.scale}]`; }
protected static [Symbol.toStringTag] = ((proto: Decimal) => {
(<any>proto).scale = null;
Expand All @@ -339,9 +337,8 @@ export interface Date_<T extends Dates = Dates> extends DataType<T> { TArray: In
/** @ignore */
export class Date_<T extends Dates = Dates> extends DataType<T> {
constructor(public readonly unit: DateUnit) {
super();
super(Type.Date as T);
}
public get typeId() { return Type.Date as T; }
public toString() { return `Date${(this.unit + 1) * 32}<${DateUnit[this.unit]}>`; }
protected static [Symbol.toStringTag] = ((proto: Date_) => {
(<any>proto).unit = null;
Expand Down Expand Up @@ -375,9 +372,8 @@ interface Time_<T extends Times = Times> extends DataType<T> {
class Time_<T extends Times = Times> extends DataType<T> {
constructor(public readonly unit: TimesType[T]['unit'],
public readonly bitWidth: TimeBitWidth) {
super();
super(Type.Time as T);
}
public get typeId() { return Type.Time as T; }
public toString() { return `Time${this.bitWidth}<${TimeUnit[this.unit]}>`; }
public get ArrayType() {
switch (this.bitWidth) {
Expand Down Expand Up @@ -418,9 +414,8 @@ interface Timestamp_<T extends Timestamps = Timestamps> extends DataType<T> {
class Timestamp_<T extends Timestamps = Timestamps> extends DataType<T> {
constructor(public readonly unit: TimeUnit,
public readonly timezone?: string | null) {
super();
super(Type.Timestamp as T);
}
public get typeId() { return Type.Timestamp as T; }
public toString() { return `Timestamp<${TimeUnit[this.unit]}${this.timezone ? `, ${this.timezone}` : ``}>`; }
protected static [Symbol.toStringTag] = ((proto: Timestamp_) => {
(<any>proto).unit = null;
Expand Down Expand Up @@ -453,9 +448,8 @@ interface Interval_<T extends Intervals = Intervals> extends DataType<T> {
/** @ignore */
class Interval_<T extends Intervals = Intervals> extends DataType<T> {
constructor(public readonly unit: IntervalUnit) {
super();
super(Type.Interval as T);
}
public get typeId() { return Type.Interval as T; }
public toString() { return `Interval<${IntervalUnit[this.unit]}>`; }
protected static [Symbol.toStringTag] = ((proto: Interval_) => {
(<any>proto).unit = null;
Expand Down Expand Up @@ -483,9 +477,8 @@ export interface Duration<T extends Durations = Durations> extends DataType<T> {
/** @ignore */
export class Duration<T extends Durations = Durations> extends DataType<T> {
constructor(public readonly unit: TimeUnit) {
super();
super(Type.Duration as T);
}
public get typeId() { return Type.Duration as T; }
public toString() { return `Duration<${TimeUnit[this.unit]}>`; }
protected static [Symbol.toStringTag] = ((proto: Duration) => {
(<any>proto).unit = null;
Expand Down Expand Up @@ -513,11 +506,10 @@ export interface List<T extends DataType = any> extends DataType<Type.List, { [0
/** @ignore */
export class List<T extends DataType = any> extends DataType<Type.List, { [0]: T }> {
constructor(child: Field<T>) {
super();
super(Type.List);
this.children = [child];
}
public declare readonly children: Field<T>[];
public get typeId() { return Type.List as Type.List; }
public toString() { return `List<${this.valueType}>`; }
public get valueType(): T { return this.children[0].type as T; }
public get valueField(): Field<T> { return this.children[0] as Field<T>; }
Expand All @@ -540,10 +532,9 @@ export class Struct<T extends TypeMap = any> extends DataType<Type.Struct, T> {
public declare _row: StructRow<T>;
public declare readonly children: Field<T[keyof T]>[];
constructor(children: Field<T[keyof T]>[]) {
super();
super(Type.Struct);
this.children = children;
}
public get typeId() { return Type.Struct as Type.Struct; }
public toString() { return `Struct<{${this.children.map((f) => `${f.name}:${f.type}`).join(`, `)}}>`; }
protected static [Symbol.toStringTag] = ((proto: Struct) => {
(<any>proto).children = null;
Expand All @@ -564,13 +555,12 @@ class Union_<T extends Unions = Unions> extends DataType<T> {
constructor(mode: UnionMode,
typeIds: number[] | Int32Array,
children: Field<any>[]) {
super();
super(Type.Union as T);
this.mode = mode;
this.children = children;
this.typeIds = typeIds = Int32Array.from(typeIds);
this.typeIdToChildIndex = typeIds.reduce((typeIdToChildIndex, typeId, idx) => (typeIdToChildIndex[typeId] = idx) && typeIdToChildIndex || typeIdToChildIndex, Object.create(null) as { [key: number]: number });
}
public get typeId() { return Type.Union as T; }
public toString() {
return `${this[Symbol.toStringTag]}<${this.children.map((x) => `${x.type}`).join(` | `)
}>`;
Expand Down Expand Up @@ -611,9 +601,8 @@ export interface FixedSizeBinary extends DataType<Type.FixedSizeBinary> {
/** @ignore */
export class FixedSizeBinary extends DataType<Type.FixedSizeBinary> {
constructor(public readonly byteWidth: number) {
super();
super(Type.FixedSizeBinary);
}
public get typeId() { return Type.FixedSizeBinary as Type.FixedSizeBinary; }
public toString() { return `FixedSizeBinary[${this.byteWidth}]`; }
protected static [Symbol.toStringTag] = ((proto: FixedSizeBinary) => {
(<any>proto).byteWidth = null;
Expand All @@ -632,10 +621,9 @@ export interface FixedSizeList<T extends DataType = any> extends DataType<Type.F
export class FixedSizeList<T extends DataType = any> extends DataType<Type.FixedSizeList, { [0]: T }> {
public declare readonly children: Field<T>[];
constructor(public readonly listSize: number, child: Field<T>) {
super();
super(Type.FixedSizeList);
this.children = [child];
}
public get typeId() { return Type.FixedSizeList as Type.FixedSizeList; }
public get valueType(): T { return this.children[0].type as T; }
public get valueField(): Field<T> { return this.children[0] as Field<T>; }
public get ArrayType(): T['ArrayType'] { return this.valueType.ArrayType; }
Expand All @@ -657,7 +645,7 @@ export interface Map_<TKey extends DataType = any, TValue extends DataType = any
/** @ignore */
export class Map_<TKey extends DataType = any, TValue extends DataType = any> extends DataType<Type.Map, { [0]: Struct<{ key: TKey; value: TValue }> }> {
constructor(entries: Field<Struct<{ key: TKey; value: TValue }>>, keysSorted = false) {
super();
super(Type.Map);
this.children = [entries];
this.keysSorted = keysSorted;
// ARROW-8716
Expand All @@ -678,7 +666,6 @@ export class Map_<TKey extends DataType = any, TValue extends DataType = any> ex
}
public declare readonly keysSorted: boolean;
public declare readonly children: Field<Struct<{ key: TKey; value: TValue }>>[];
public get typeId() { return Type.Map as Type.Map; }
public get keyType(): TKey { return this.children[0].type.children[0].type as TKey; }
public get valueType(): TValue { return this.children[0].type.children[1].type as TValue; }
public get childType() { return this.children[0].type as Struct<{ key: TKey; value: TValue }>; }
Expand Down Expand Up @@ -709,13 +696,12 @@ export class Dictionary<T extends DataType = any, TKey extends TKeys = TKeys> ex
public declare readonly dictionary: T;
public declare readonly isOrdered: boolean;
constructor(dictionary: T, indices: TKey, id?: bigint | number | null, isOrdered?: boolean | null) {
super();
super(Type.Dictionary);
this.indices = indices;
this.dictionary = dictionary;
this.isOrdered = isOrdered || false;
this.id = id == null ? getId() : bigIntToNumber(id);
}
public get typeId() { return Type.Dictionary as Type.Dictionary; }
public get children() { return this.dictionary.children; }
public get valueType(): T { return this.dictionary as T; }
public get ArrayType(): T['ArrayType'] { return this.dictionary.ArrayType; }
Expand Down

0 comments on commit 90f7eca

Please sign in to comment.