Skip to content

Commit 262dacb

Browse files
KSDaemonigorlukanin
authored andcommitted
fix(tesseract): Fix member name case conversion (#10064)
* fix(tesseract): Fix member name case conversion Prepend "_" even to the first UPPERCASE letter in the name * add tests * fix tests * cargo fmt
1 parent 81e553e commit 262dacb

File tree

6 files changed

+106
-37
lines changed

6 files changed

+106
-37
lines changed

packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,31 @@ describe('SQL Generation', () => {
361361
type: 'string',
362362
sql: 'source'
363363
},
364+
// dimensions for testing letter cases
365+
my_favorite_source: {
366+
type: 'string',
367+
sql: 'source'
368+
},
369+
My_favorite_source: {
370+
type: 'string',
371+
sql: 'source'
372+
},
373+
MY_favorite_source: {
374+
type: 'string',
375+
sql: 'source'
376+
},
377+
My_Favorite_Source: {
378+
type: 'string',
379+
sql: 'source'
380+
},
381+
MY_Favorite_SOURCE: {
382+
type: 'string',
383+
sql: 'source'
384+
},
385+
MY_FAVORITE_SOURCE: {
386+
type: 'string',
387+
sql: 'source'
388+
},
364389
created_at: {
365390
type: 'time',
366391
sql: 'created_at',
@@ -5372,4 +5397,54 @@ cubes:
53725397
]);
53735398
});
53745399
});
5400+
5401+
it('Checking member name letter cases', async () => {
5402+
await compiler.compile();
5403+
5404+
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
5405+
measures: [],
5406+
dimensions: [
5407+
'visitors.my_favorite_source',
5408+
'visitors.My_favorite_source',
5409+
'visitors.MY_favorite_source',
5410+
'visitors.My_Favorite_Source',
5411+
'visitors.MY_Favorite_SOURCE',
5412+
'visitors.MY_FAVORITE_SOURCE',
5413+
],
5414+
order: [{
5415+
id: 'visitors.created_at'
5416+
}],
5417+
timezone: 'America/Los_Angeles'
5418+
});
5419+
5420+
const res = await dbRunner.testQuery(query.buildSqlAndParams());
5421+
console.log(JSON.stringify(res));
5422+
5423+
expect(res).toEqual([
5424+
{
5425+
visitors___m_y__f_a_v_o_r_i_t_e__s_o_u_r_c_e: null,
5426+
visitors___m_y__favorite__s_o_u_r_c_e: null,
5427+
visitors___m_y_favorite_source: null,
5428+
visitors___my__favorite__source: null,
5429+
visitors___my_favorite_source: null,
5430+
visitors__my_favorite_source: null,
5431+
},
5432+
{
5433+
visitors___m_y__f_a_v_o_r_i_t_e__s_o_u_r_c_e: 'google',
5434+
visitors___m_y__favorite__s_o_u_r_c_e: 'google',
5435+
visitors___m_y_favorite_source: 'google',
5436+
visitors___my__favorite__source: 'google',
5437+
visitors___my_favorite_source: 'google',
5438+
visitors__my_favorite_source: 'google',
5439+
},
5440+
{
5441+
visitors___m_y__f_a_v_o_r_i_t_e__s_o_u_r_c_e: 'some',
5442+
visitors___m_y__favorite__s_o_u_r_c_e: 'some',
5443+
visitors___m_y_favorite_source: 'some',
5444+
visitors___my__favorite__source: 'some',
5445+
visitors___my_favorite_source: 'some',
5446+
visitors__my_favorite_source: 'some',
5447+
},
5448+
]);
5449+
});
53755450
});

packages/cubejs-schema-compiler/test/integration/postgres/views-join-order-2.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { prepareJsCompiler } from '../../unit/PrepareCompiler';
22
import { dbRunner } from './PostgresDBRunner';
3-
import { transformResultsForTesseractIfNeeded } from '../../unit/utils';
43

54
describe('Views Join Order 2', () => {
65
jest.setTimeout(200000);
@@ -161,7 +160,7 @@ cube('D', {
161160
total: true,
162161
renewQuery: false,
163162
limit: 1
164-
}, transformResultsForTesseractIfNeeded([{
163+
}, [{
165164
view___a_id: 1,
166165
view___a_name: 'a',
167166
view___b_id: 2,
@@ -170,5 +169,5 @@ cube('D', {
170169
view___d_name: 'd',
171170
view___e_id: 4,
172171
view___e_name: 'e',
173-
}]), { compiler, joinGraph, cubeEvaluator }));
172+
}], { compiler, joinGraph, cubeEvaluator }));
174173
});

packages/cubejs-schema-compiler/test/integration/postgres/views-join-order-3.test.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { prepareJsCompiler } from '../../unit/PrepareCompiler';
22
import { dbRunner } from './PostgresDBRunner';
3-
import { transformResultsForTesseractIfNeeded } from '../../unit/utils';
43

54
/**
65
* This tests the cube join correctness for cases, when there are
@@ -126,9 +125,9 @@ view(\`V\`, {
126125
timeDimensions: [],
127126
segments: [],
128127
filters: [],
129-
}, transformResultsForTesseractIfNeeded([{
128+
}, [{
130129
b___activity_balance: 125,
131-
}]), { compiler, joinGraph, cubeEvaluator });
130+
}], { compiler, joinGraph, cubeEvaluator });
132131

133132
expect(sql).toMatch(/AS "b"/);
134133
expect(sql).toMatch(/AS "d"/);
@@ -143,36 +142,36 @@ view(\`V\`, {
143142
timeDimensions: [],
144143
segments: [],
145144
filters: [],
146-
}, transformResultsForTesseractIfNeeded([{
145+
}, [{
147146
v___activity_balance: 125,
148-
}]), { compiler, joinGraph, cubeEvaluator }));
147+
}], { compiler, joinGraph, cubeEvaluator }));
149148

150149
it('correct join for simple view F-dimension', async () => dbRunner.runQueryTest({
151150
dimensions: ['V.PlanCode'],
152151
timeDimensions: [],
153152
segments: [],
154153
filters: [],
155-
}, transformResultsForTesseractIfNeeded([{
154+
}, [{
156155
v___plan_code: 'PLAN_CODE',
157-
}]), { compiler, joinGraph, cubeEvaluator }));
156+
}], { compiler, joinGraph, cubeEvaluator }));
158157

159158
it('correct join for view F-dimension + B-dimension', async () => dbRunner.runQueryTest({
160159
dimensions: ['V.PlanCode', 'V.ActivityBalance'],
161160
timeDimensions: [],
162161
segments: [],
163162
filters: [],
164-
}, transformResultsForTesseractIfNeeded([{
163+
}, [{
165164
v___plan_code: 'PLAN_CODE',
166165
v___activity_balance: 125,
167-
}]), { compiler, joinGraph, cubeEvaluator }));
166+
}], { compiler, joinGraph, cubeEvaluator }));
168167

169168
it('correct join for view B-dimension + F-dimension', async () => dbRunner.runQueryTest({
170169
dimensions: ['V.ActivityBalance', 'V.PlanCode'],
171170
timeDimensions: [],
172171
segments: [],
173172
filters: [],
174-
}, transformResultsForTesseractIfNeeded([{
173+
}, [{
175174
v___activity_balance: 125,
176175
v___plan_code: 'PLAN_CODE',
177-
}]), { compiler, joinGraph, cubeEvaluator }));
176+
}], { compiler, joinGraph, cubeEvaluator }));
178177
});

packages/cubejs-schema-compiler/test/integration/postgres/views-join-order-join-maps.test.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { prepareJsCompiler } from '../../unit/PrepareCompiler';
22
import { dbRunner } from './PostgresDBRunner';
3-
import { transformResultsForTesseractIfNeeded } from '../../unit/utils';
43

54
describe('Views Join Order using join maps', () => {
65
jest.setTimeout(200000);
@@ -140,11 +139,11 @@ cube('D', {
140139
segments: [],
141140
filters: [],
142141
total: true,
143-
}, transformResultsForTesseractIfNeeded([{
142+
}, [{
144143
view___a_id: 1,
145144
view___a_name: 'a',
146145
view___a_d_name: 'd3',
147-
}]), { compiler, joinGraph, cubeEvaluator });
146+
}], { compiler, joinGraph, cubeEvaluator });
148147

149148
expect(sql).toMatch(/AS "b"/);
150149
expect(sql).toMatch(/AS "c"/);
@@ -166,11 +165,11 @@ cube('D', {
166165
segments: [],
167166
filters: [],
168167
total: true,
169-
}, transformResultsForTesseractIfNeeded([{
168+
}, [{
170169
view___a_id: 1,
171170
view___a_name: 'a',
172171
view___a_c_name: 'c1',
173-
}]), { compiler, joinGraph, cubeEvaluator });
172+
}], { compiler, joinGraph, cubeEvaluator });
174173

175174
expect(sql).toMatch(/AS "b"/);
176175
expect(sql).toMatch(/AS "c"/);
@@ -193,12 +192,12 @@ cube('D', {
193192
segments: [],
194193
filters: [],
195194
total: true,
196-
}, transformResultsForTesseractIfNeeded([{
195+
}, [{
197196
view___a_id: 1,
198197
view___a_name: 'a',
199198
view___a_c_name: 'c1',
200199
view___a_d_name: 'd3',
201-
}]), { compiler, joinGraph, cubeEvaluator });
200+
}], { compiler, joinGraph, cubeEvaluator });
202201

203202
expect(sql).toMatch(/AS "b"/);
204203
expect(sql).toMatch(/AS "c"/);

packages/cubejs-schema-compiler/test/unit/utils.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -769,18 +769,3 @@ export function createJoinedCubesSchema(): string {
769769
});
770770
`;
771771
}
772-
773-
export function transformResultsForTesseractIfNeeded(results: Record<string, any>[]) {
774-
if (getEnv('nativeSqlPlanner')) {
775-
return results.map(record => {
776-
const fixedRecord: Record<string, any> = {};
777-
for (const [key, value] of Object.entries(record)) {
778-
const fixedKey = key.replace(/___/g, '__');
779-
fixedRecord[fixedKey] = value;
780-
}
781-
return fixedRecord;
782-
});
783-
}
784-
785-
return results;
786-
}

rust/cubesqlplanner/cubesqlplanner/src/planner/sql_templates/plan.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,22 @@ impl PlanSqlTemplates {
161161
} else {
162162
format!("")
163163
};
164+
165+
// For strange reasons, the javascript snake caser used in cube
166+
// changes first UPPERCASE letter to "_lowercase", prepending "_"
167+
// This is weird, but to be compatible we have to add it too.
168+
let mut member_alias = Self::alias_name(name);
169+
170+
if let Some(fl) = name.chars().next() {
171+
if fl.is_uppercase() {
172+
member_alias = format!("_{}", member_alias);
173+
}
174+
}
175+
164176
format!(
165177
"{}__{}{}",
166178
Self::alias_name(cube_name),
167-
Self::alias_name(name),
179+
member_alias,
168180
suffix
169181
)
170182
}

0 commit comments

Comments
 (0)