diff --git a/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts b/packages/cubejs-schema-compiler/src/scaffolding/ScaffoldingSchema.ts index 0c91881b2cc57..4d4fa2aeef0e3 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))) { 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..83508e8d24dc1 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 floatSchemas = { + 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(floatSchemas); + floatSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); + }); + }); + + it('should map REAL type to number', () => { + const realSchemas = { + public: { + test: [{ name: 'real_col', type: 'REAL', attributes: [] }] + } + }; + const schema = new ScaffoldingSchema(realSchemas); + expect((schema as any).columnType(realSchemas.public.test[0])).toBe('number'); + }); + + it('should map SERIAL types to number', () => { + const serialSchemas = { + public: { + test: [ + { name: 'serial_col', type: 'SERIAL', attributes: [] }, + { name: 'bigserial_col', type: 'BIGSERIAL', attributes: [] }, + { name: 'smallserial_col', type: 'SMALLSERIAL', attributes: [] }, + ] + } + }; + 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 moneySchemas = { + public: { + test: [ + { name: 'money_col', type: 'MONEY', attributes: [] }, + { name: 'smallmoney_col', type: 'SMALLMONEY', attributes: [] }, + ] + } + }; + 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 intSchemas = { + 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(intSchemas); + intSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); + }); + }); + + it('should be case insensitive for type matching', () => { + const caseSchemas = { + public: { + test: [ + { name: 'float_lower', type: 'float', attributes: [] }, + { name: 'float_upper', type: 'FLOAT', attributes: [] }, + { name: 'float_mixed', type: 'Float', attributes: [] }, + ] + } + }; + const schema = new ScaffoldingSchema(caseSchemas); + caseSchemas.public.test.forEach(col => { + expect((schema as any).columnType(col)).toBe('number'); + }); + }); + }); });