From c588a132436e5406929695ca00f19982f675b1fa Mon Sep 17 00:00:00 2001 From: jiahua Date: Wed, 22 Oct 2025 18:13:44 +0800 Subject: [PATCH 1/3] fix(schema-compiler): Add missing numeric types to ScaffoldingSchema columnType mapping --- .../src/scaffolding/ScaffoldingSchema.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts b/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts index 0c91881b2cc57..624614a96b13e 100644 --- a/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts +++ b/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts @@ -387,7 +387,16 @@ export class ScaffoldingSchema { if (['time', 'date'].find(t => type.includes(t))) { return ColumnType.Time; - } else if (['int', 'dec', 'double', 'numb'].find(t => type.includes(t))) { + } else if ([ + 'int', // integer, bigint, smallint, tinyint, mediumint, uint8, uint16, uint32, uint64, uinteger, ubigint, usmallint, hugeint, byteint, etc. + 'dec', // decimal + 'double', // double, double precision + 'numb', // number, numeric, bignumeric + 'float', // float, float4, float8, float32, float64, binary_float + 'real', // real + 'serial', // serial, bigserial, smallserial + 'money', // money, smallmoney + ].find(t => type.includes(t))) { // enums are not Numbers return ColumnType.Number; } else if (['bool'].find(t => type.includes(t))) { From 6248945c4594c29c305db2236123f2810d564ed7 Mon Sep 17 00:00:00 2001 From: jiahua Date: Thu, 23 Oct 2025 10:17:14 +0800 Subject: [PATCH 2/3] test(schema-compiler): Add missing numeric types to ScaffoldingSchema columnType mapping --- .../test/unit/scaffolding-schema.test.ts | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts b/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts index 829a7263ae3b4..dc9dfab8be809 100644 --- a/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts +++ b/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts @@ -554,4 +554,105 @@ describe('ScaffoldingSchema', () => { } ]); }); + + describe('columnType mapping for numeric types', () => { + it('should map FLOAT types to number', () => { + const schemas = { + public: { + test: [ + { name: 'float_col', type: 'FLOAT', attributes: [] }, + { name: 'float4_col', type: 'FLOAT4', attributes: [] }, + { name: 'float8_col', type: 'FLOAT8', attributes: [] }, + { name: 'float32_col', type: 'FLOAT32', attributes: [] }, + { name: 'float64_col', type: 'FLOAT64', attributes: [] }, + ] + } + }; + const schema = new ScaffoldingSchema(schemas); + schemas.public.test.forEach(col => { + expect(schema['columnType'](col)).toBe('number'); + }); + }); + + it('should map REAL type to number', () => { + const schemas = { + public: { + test: [{ name: 'real_col', type: 'REAL', attributes: [] }] + } + }; + const schema = new ScaffoldingSchema(schemas); + expect(schema['columnType'](schemas.public.test[0])).toBe('number'); + }); + + it('should map SERIAL types to number', () => { + const schemas = { + public: { + test: [ + { name: 'serial_col', type: 'SERIAL', attributes: [] }, + { name: 'bigserial_col', type: 'BIGSERIAL', attributes: [] }, + { name: 'smallserial_col', type: 'SMALLSERIAL', attributes: [] }, + ] + } + }; + const schema = new ScaffoldingSchema(schemas); + schemas.public.test.forEach(col => { + expect(schema['columnType'](col)).toBe('number'); + }); + }); + + it('should map MONEY types to number', () => { + const schemas = { + public: { + test: [ + { name: 'money_col', type: 'MONEY', attributes: [] }, + { name: 'smallmoney_col', type: 'SMALLMONEY', attributes: [] }, + ] + } + }; + const schema = new ScaffoldingSchema(schemas); + schemas.public.test.forEach(col => { + expect(schema['columnType'](col)).toBe('number'); + }); + }); + + it('should map various integer types to number (covered by int keyword)', () => { + const schemas = { + public: { + test: [ + // Standard integer types + { name: 'tinyint_col', type: 'TINYINT', attributes: [] }, + { name: 'mediumint_col', type: 'MEDIUMINT', attributes: [] }, + { name: 'hugeint_col', type: 'HUGEINT', attributes: [] }, + // Unsigned integer types + { name: 'uint8_col', type: 'UINT8', attributes: [] }, + { name: 'uint32_col', type: 'UINT32', attributes: [] }, + { name: 'uinteger_col', type: 'UINTEGER', attributes: [] }, + { name: 'ubigint_col', type: 'UBIGINT', attributes: [] }, + // Other variants + { name: 'byteint_col', type: 'BYTEINT', attributes: [] }, + ] + } + }; + const schema = new ScaffoldingSchema(schemas); + schemas.public.test.forEach(col => { + expect(schema['columnType'](col)).toBe('number'); + }); + }); + + it('should be case insensitive for type matching', () => { + const schemas = { + public: { + test: [ + { name: 'float_lower', type: 'float', attributes: [] }, + { name: 'float_upper', type: 'FLOAT', attributes: [] }, + { name: 'float_mixed', type: 'Float', attributes: [] }, + ] + } + }; + const schema = new ScaffoldingSchema(schemas); + schemas.public.test.forEach(col => { + expect(schema['columnType'](col)).toBe('number'); + }); + }); + }); }); From a0ca6482a3fdb38a8694104c7b6adb61628bb0d8 Mon Sep 17 00:00:00 2001 From: jiahua Date: Thu, 23 Oct 2025 10:40:49 +0800 Subject: [PATCH 3/3] fix: yarn lint --- .../src/scaffolding/ScaffoldingSchema.ts | 16 +++---- .../test/unit/scaffolding-schema.test.ts | 46 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts b/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts index 624614a96b13e..4d4fa2aeef0e3 100644 --- a/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts +++ b/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts @@ -388,14 +388,14 @@ export class ScaffoldingSchema { if (['time', 'date'].find(t => type.includes(t))) { return ColumnType.Time; } else if ([ - 'int', // integer, bigint, smallint, tinyint, mediumint, uint8, uint16, uint32, uint64, uinteger, ubigint, usmallint, hugeint, byteint, etc. - 'dec', // decimal - 'double', // double, double precision - 'numb', // number, numeric, bignumeric - 'float', // float, float4, float8, float32, float64, binary_float - 'real', // real - 'serial', // serial, bigserial, smallserial - 'money', // money, smallmoney + 'int', // integer, bigint, smallint, tinyint, mediumint, uint8, uint16, uint32, uint64, uinteger, ubigint, usmallint, hugeint, byteint, etc. + 'dec', // decimal + 'double', // double, double precision + 'numb', // number, numeric, bignumeric + 'float', // float, float4, float8, float32, float64, binary_float + 'real', // real + 'serial', // serial, bigserial, smallserial + 'money', // money, smallmoney ].find(t => type.includes(t))) { // enums are not Numbers return ColumnType.Number; diff --git a/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts b/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts index dc9dfab8be809..83508e8d24dc1 100644 --- a/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts +++ b/packages/cubejs-schema-compiler/test/unit/scaffolding-schema.test.ts @@ -557,7 +557,7 @@ describe('ScaffoldingSchema', () => { describe('columnType mapping for numeric types', () => { it('should map FLOAT types to number', () => { - const schemas = { + const floatSchemas = { public: { test: [ { name: 'float_col', type: 'FLOAT', attributes: [] }, @@ -568,24 +568,24 @@ describe('ScaffoldingSchema', () => { ] } }; - const schema = new ScaffoldingSchema(schemas); - schemas.public.test.forEach(col => { - expect(schema['columnType'](col)).toBe('number'); + const schema = new ScaffoldingSchema(floatSchemas); + floatSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); }); }); it('should map REAL type to number', () => { - const schemas = { + const realSchemas = { public: { test: [{ name: 'real_col', type: 'REAL', attributes: [] }] } }; - const schema = new ScaffoldingSchema(schemas); - expect(schema['columnType'](schemas.public.test[0])).toBe('number'); + const schema = new ScaffoldingSchema(realSchemas); + expect((schema as any).columnType(realSchemas.public.test[0])).toBe('number'); }); it('should map SERIAL types to number', () => { - const schemas = { + const serialSchemas = { public: { test: [ { name: 'serial_col', type: 'SERIAL', attributes: [] }, @@ -594,14 +594,14 @@ describe('ScaffoldingSchema', () => { ] } }; - const schema = new ScaffoldingSchema(schemas); - schemas.public.test.forEach(col => { - expect(schema['columnType'](col)).toBe('number'); + const schema = new ScaffoldingSchema(serialSchemas); + serialSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); }); }); it('should map MONEY types to number', () => { - const schemas = { + const moneySchemas = { public: { test: [ { name: 'money_col', type: 'MONEY', attributes: [] }, @@ -609,14 +609,14 @@ describe('ScaffoldingSchema', () => { ] } }; - const schema = new ScaffoldingSchema(schemas); - schemas.public.test.forEach(col => { - expect(schema['columnType'](col)).toBe('number'); + const schema = new ScaffoldingSchema(moneySchemas); + moneySchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); }); }); it('should map various integer types to number (covered by int keyword)', () => { - const schemas = { + const intSchemas = { public: { test: [ // Standard integer types @@ -633,14 +633,14 @@ describe('ScaffoldingSchema', () => { ] } }; - const schema = new ScaffoldingSchema(schemas); - schemas.public.test.forEach(col => { - expect(schema['columnType'](col)).toBe('number'); + const schema = new ScaffoldingSchema(intSchemas); + intSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); }); }); it('should be case insensitive for type matching', () => { - const schemas = { + const caseSchemas = { public: { test: [ { name: 'float_lower', type: 'float', attributes: [] }, @@ -649,9 +649,9 @@ describe('ScaffoldingSchema', () => { ] } }; - const schema = new ScaffoldingSchema(schemas); - schemas.public.test.forEach(col => { - expect(schema['columnType'](col)).toBe('number'); + const schema = new ScaffoldingSchema(caseSchemas); + caseSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); }); }); });