diff --git a/DEPRECATION.md b/DEPRECATION.md index 875697abd727a..89159b4a361f6 100644 --- a/DEPRECATION.md +++ b/DEPRECATION.md @@ -46,7 +46,7 @@ features: | Deprecated | [`checkAuthMiddleware`](#checkauthmiddleware) | v0.26.0 | v0.36.0 | | Removed | [Node.js 10](#nodejs-10) | v0.26.0 | v0.29.0 | | Removed | [Node.js 15](#nodejs-15) | v0.26.0 | v0.32.0 | -| Deprecated | [`USER_CONTEXT`](#user_context) | v0.26.0 | v0.36.0 | +| Removed | [`USER_CONTEXT`](#user_context) | v0.26.0 | v0.36.0 | | Deprecated | [`authInfo`](#authinfo) | v0.26.0 | | | Deprecated | [Prefix Redis environment variables with `CUBEJS_`](#prefix-redis-environment-variables-with-cubejs_) | v0.27.0 | v0.36.0 | | Removed | [Node.js 12](#nodejs-12) | v0.29.0 | v0.32.0 | @@ -211,14 +211,6 @@ no more updates. Please upgrade to Node.js 12 or higher. `USER_CONTEXT` has been renamed to `SECURITY_CONTEXT`. -Deprecated: - -```js -cube(`visitors`, { - sql: `select * from visitors WHERE ${USER_CONTEXT.source.filter("source")}`, -}); -``` - You should use: ```js diff --git a/packages/cubejs-schema-compiler/src/compiler/CubeSymbols.js b/packages/cubejs-schema-compiler/src/compiler/CubeSymbols.js index c026656e9ffdb..329e3ae97baa3 100644 --- a/packages/cubejs-schema-compiler/src/compiler/CubeSymbols.js +++ b/packages/cubejs-schema-compiler/src/compiler/CubeSymbols.js @@ -9,7 +9,6 @@ import { BaseQuery } from '../adapter'; const FunctionRegex = /function\s+\w+\(([A-Za-z0-9_,]*)|\(([\s\S]*?)\)\s*=>|\(?(\w+)\)?\s*=>/; const CONTEXT_SYMBOLS = { - USER_CONTEXT: 'securityContext', SECURITY_CONTEXT: 'securityContext', FILTER_PARAMS: 'filterParams', FILTER_GROUP: 'filterGroup', @@ -495,6 +494,11 @@ export class CubeSymbols { resolveSymbol(cubeName, name) { const { sqlResolveFn, contextSymbols, collectJoinHints } = this.resolveSymbolsCallContext || {}; + + if (name === 'USER_CONTEXT') { + throw new Error('Support for USER_CONTEXT was removed, please migrate to SECURITY_CONTEXT.'); + } + if (CONTEXT_SYMBOLS[name]) { // always resolves if contextSymbols aren't passed for transpile step const symbol = contextSymbols && contextSymbols[CONTEXT_SYMBOLS[name]] || {}; diff --git a/packages/cubejs-schema-compiler/src/compiler/transpilers/ValidationTranspiler.ts b/packages/cubejs-schema-compiler/src/compiler/transpilers/ValidationTranspiler.ts index 74055f064ccd0..a8b9c49b23e07 100644 --- a/packages/cubejs-schema-compiler/src/compiler/transpilers/ValidationTranspiler.ts +++ b/packages/cubejs-schema-compiler/src/compiler/transpilers/ValidationTranspiler.ts @@ -1,18 +1,17 @@ -/* eslint-disable no-restricted-syntax */ -import { TranspilerInterface, TraverseObject } from './transpiler.interface'; -import { ErrorReporter } from '../ErrorReporter'; +import type { TranspilerInterface, TraverseObject } from './transpiler.interface'; +import type { ErrorReporter } from '../ErrorReporter'; -// @todo It's not possible to do a warning inside CubeSymbols.resolveSymbol, -// because it doesnt have ErrorReporter, restructure? export class ValidationTranspiler implements TranspilerInterface { public traverseObject(reporter: ErrorReporter): TraverseObject { return { Identifier: path => { if (path.node.name === 'USER_CONTEXT') { - reporter.warning({ - message: 'USER_CONTEXT was deprecated in favor of SECURITY_CONTEXT.', - loc: path.node.loc, - }); + reporter.error( + 'Support for USER_CONTEXT was removed, please migrate to SECURITY_CONTEXT.', + path.node.loc?.filename, + path.node.loc?.start.line, + path.node.loc?.start.column, + ); } } }; diff --git a/packages/cubejs-schema-compiler/test/integration/clickhouse/clickhouse-graph-builder.test.ts b/packages/cubejs-schema-compiler/test/integration/clickhouse/clickhouse-graph-builder.test.ts index e2fcf9594cfb6..599d764f0cdbf 100644 --- a/packages/cubejs-schema-compiler/test/integration/clickhouse/clickhouse-graph-builder.test.ts +++ b/packages/cubejs-schema-compiler/test/integration/clickhouse/clickhouse-graph-builder.test.ts @@ -18,13 +18,13 @@ describe('ClickHouse JoinGraph', () => { type: 'number', sql: new Function('visitor_revenue', 'visitor_count', 'return visitor_revenue + "/" + visitor_count') } - + cube(\`visitors\`, { sql: \` - select * from visitors WHERE \${USER_CONTEXT.source.filter('source')} AND - \${USER_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} + select * from visitors WHERE \${SECURITY_CONTEXT.source.filter('source')} AND + \${SECURITY_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} \`, - + refreshKey: { sql: 'SELECT 1', }, @@ -113,24 +113,24 @@ describe('ClickHouse JoinGraph', () => { type: 'time', sql: 'created_at' }, - + createdAtSqlUtils: { type: 'time', sql: SQL_UTILS.convertTz('created_at') }, - + checkins: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true }, - + subQueryFail: { sql: '2', type: \`number\`, subQuery: true }, - + doubledCheckings: { sql: \`\${checkins} * 2\`, type: 'number' @@ -210,7 +210,7 @@ describe('ClickHouse JoinGraph', () => { subQuery: true }, }, - + // preAggregations: { // checkinSource: { // type: 'rollup', @@ -255,19 +255,19 @@ describe('ClickHouse JoinGraph', () => { } } }) - + cube('ReferenceVisitors', { sql: \` - select * from \${visitors.sql()} as t + select * from \${visitors.sql()} as t WHERE \${FILTER_PARAMS.ReferenceVisitors.createdAt.filter(\`addDays(t.created_at, 28)\`)} AND \${FILTER_PARAMS.ReferenceVisitors.createdAt.filter((from, to) => \`(addDays(t.created_at,28)) >= parseDateTimeBestEffort(\${from}) AND (addDays(t.created_at, 28)) <= parseDateTimeBestEffort(\${to})\`)} \`, - + measures: { count: { type: 'count' }, - + googleSourcedCount: { type: 'count', filters: [{ @@ -275,7 +275,7 @@ describe('ClickHouse JoinGraph', () => { }] }, }, - + dimensions: { createdAt: { type: 'time', diff --git a/packages/cubejs-schema-compiler/test/integration/mssql/mssql-ungrouped.test.ts b/packages/cubejs-schema-compiler/test/integration/mssql/mssql-ungrouped.test.ts index 19ca82e9bc472..ddc7c4d21399f 100644 --- a/packages/cubejs-schema-compiler/test/integration/mssql/mssql-ungrouped.test.ts +++ b/packages/cubejs-schema-compiler/test/integration/mssql/mssql-ungrouped.test.ts @@ -16,15 +16,15 @@ describe('MSSqlUngrouped', () => { type: 'number', sql: new Function('visitor_revenue', 'visitor_count', 'return visitor_revenue + "/" + visitor_count') } - + cube(\`visitors\`, { sql: \` - select * from ##visitors WHERE \${USER_CONTEXT.source.filter('source')} AND - \${USER_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} + select * from ##visitors WHERE \${SECURITY_CONTEXT.source.filter('source')} AND + \${SECURITY_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} \`, - + rewriteQueries: true, - + refreshKey: { sql: 'SELECT 1', }, @@ -122,37 +122,37 @@ describe('MSSqlUngrouped', () => { type: 'time', sql: 'created_at' }, - + createdAtSqlUtils: { type: 'time', sql: SQL_UTILS.convertTz('created_at') }, - + checkins: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true }, - + checkinsRolling: { sql: \`\${visitor_checkins.visitorCheckinsRolling}\`, type: \`number\`, subQuery: true }, - + checkinsWithPropagation: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true, propagateFiltersToSubQuery: true }, - + subQueryFail: { sql: '2', type: \`number\`, subQuery: true }, - + doubledCheckings: { sql: \`\${checkins} * 2\`, type: 'number' @@ -181,11 +181,11 @@ describe('MSSqlUngrouped', () => { cube('visitor_checkins', { sql: \` - select * from ##visitor_checkins WHERE + select * from ##visitor_checkins WHERE \${FILTER_PARAMS.visitor_checkins.created_at.filter('created_at')} AND \${FILTER_GROUP(FILTER_PARAMS.visitor_checkins.created_at.filter("dateadd(day, -3, created_at)"), FILTER_PARAMS.visitor_checkins.source.filter('source'))} \`, - + rewriteQueries: true, joins: { @@ -199,14 +199,14 @@ describe('MSSqlUngrouped', () => { visitor_checkins_count: { type: 'count' }, - + visitorCheckinsRolling: { type: 'count', rollingWindow: { trailing: 'unbounded' } }, - + revenue_per_checkin: { type: 'number', sql: \`\${visitors.visitor_revenue} / \${visitor_checkins_count}\` @@ -259,7 +259,7 @@ describe('MSSqlUngrouped', () => { subQuery: true }, }, - + preAggregations: { checkinSource: { type: 'rollup', @@ -331,9 +331,9 @@ describe('MSSqlUngrouped', () => { } } }) - - - + + + `); async function runQueryTest(q, expectedResult) { diff --git a/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation-logic.test.ts b/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation-logic.test.ts index a8d2b97e974bf..7ed7423ea721d 100644 --- a/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation-logic.test.ts +++ b/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation-logic.test.ts @@ -11,15 +11,15 @@ describe('SQL Generation', () => { type: 'number', sql: new Function('visitor_revenue', 'visitor_count', 'return visitor_revenue + "/" + visitor_count') } - + cube(\`visitors\`, { sql: \` - select * from visitors WHERE \${USER_CONTEXT.source.filter('source')} AND - \${USER_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} + select * from visitors WHERE \${SECURITY_CONTEXT.source.filter('source')} AND + \${SECURITY_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} \`, - + rewriteQueries: true, - + refreshKey: { sql: 'SELECT 1', }, @@ -109,31 +109,31 @@ describe('SQL Generation', () => { type: 'time', sql: 'created_at' }, - + createdAtSqlUtils: { type: 'time', sql: SQL_UTILS.convertTz('created_at') }, - + checkins: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true }, - + checkinsWithPropagation: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true, propagateFiltersToSubQuery: true }, - + subQueryFail: { sql: '2', type: \`number\`, subQuery: true }, - + doubledCheckings: { sql: \`\${checkins} * 2\`, type: 'number' @@ -160,7 +160,7 @@ describe('SQL Generation', () => { sql: \` select * from visitor_checkins WHERE \${FILTER_PARAMS.visitor_checkins.created_at.filter('created_at')} \`, - + rewriteQueries: true, joins: { @@ -215,7 +215,7 @@ describe('SQL Generation', () => { subQuery: true }, }, - + preAggregations: { checkinSource: { type: 'rollup', @@ -260,19 +260,19 @@ describe('SQL Generation', () => { } } }) - + cube('ReferenceVisitors', { sql: \` - select * from \${visitors.sql()} as t + select * from \${visitors.sql()} as t WHERE \${FILTER_PARAMS.ReferenceVisitors.createdAt.filter(\`(t.created_at + interval '28 day')\`)} AND \${FILTER_PARAMS.ReferenceVisitors.createdAt.filter((from, to) => \`(t.created_at + interval '28 day') >= \${from} AND (t.created_at + interval '28 day') <= \${to}\`)} \`, - + measures: { count: { type: 'count' }, - + googleSourcedCount: { type: 'count', filters: [{ @@ -280,7 +280,7 @@ describe('SQL Generation', () => { }] }, }, - + dimensions: { createdAt: { type: 'time', @@ -288,14 +288,14 @@ describe('SQL Generation', () => { } } }) - + cube('CubeWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName', { sql: \` select * from cards \`, - + sqlAlias: 'cube_with_long_name', - + dataSource: 'oracle', measures: { diff --git a/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts b/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts index c890a9dd4de6c..bacaba422a337 100644 --- a/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts +++ b/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts @@ -14,15 +14,15 @@ describe('SQL Generation', () => { type: 'number', sql: new Function('visitor_revenue', 'visitor_count', 'return visitor_revenue + "/" + visitor_count') } - + cube(\`visitors\`, { sql: \` - select * from visitors WHERE \${USER_CONTEXT.source.filter('source')} AND - \${USER_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} + select * from visitors WHERE \${SECURITY_CONTEXT.source.filter('source')} AND + \${SECURITY_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)} \`, - + rewriteQueries: true, - + refreshKey: { sql: 'SELECT 1', }, @@ -226,37 +226,37 @@ describe('SQL Generation', () => { type: 'time', sql: 'updated_at' }, - + createdAtSqlUtils: { type: 'time', sql: SQL_UTILS.convertTz('created_at') }, - + checkins: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true }, - + checkinsRolling: { sql: \`\${visitor_checkins.visitorCheckinsRolling}\`, type: \`number\`, subQuery: true }, - + checkinsWithPropagation: { sql: \`\${visitor_checkins.visitor_checkins_count}\`, type: \`number\`, subQuery: true, propagateFiltersToSubQuery: true }, - + subQueryFail: { sql: '2', type: \`number\`, subQuery: true }, - + doubledCheckings: { sql: \`\${checkins} * 2\`, type: 'number' @@ -282,7 +282,7 @@ describe('SQL Generation', () => { } } }); - + view('visitors_post_aggregate', { cubes: [{ join_path: 'visitors', @@ -292,11 +292,11 @@ describe('SQL Generation', () => { cube('visitor_checkins', { sql: \` - select * from visitor_checkins WHERE + select * from visitor_checkins WHERE \${FILTER_PARAMS.visitor_checkins.created_at.filter('created_at')} AND \${FILTER_GROUP(FILTER_PARAMS.visitor_checkins.created_at.filter("(created_at - INTERVAL '3 DAY')"), FILTER_PARAMS.visitor_checkins.source.filter('source'))} \`, - + rewriteQueries: true, joins: { @@ -310,19 +310,19 @@ describe('SQL Generation', () => { visitor_checkins_count: { type: 'count' }, - + id_sum: { sql: 'id', type: 'sum' }, - + visitorCheckinsRolling: { type: 'count', rollingWindow: { trailing: 'unbounded' } }, - + revenue_per_checkin: { type: 'number', sql: \`\${visitors.visitor_revenue} / \${visitor_checkins_count}\` @@ -375,7 +375,7 @@ describe('SQL Generation', () => { subQuery: true }, }, - + preAggregations: { checkinSource: { type: 'rollup', @@ -393,7 +393,7 @@ describe('SQL Generation', () => { } } }); - + view('visitors_visitors_checkins_view', { cubes: [{ join_path: 'visitors', @@ -457,19 +457,19 @@ describe('SQL Generation', () => { } } }) - + cube('ReferenceVisitors', { sql: \` - select * from \${visitors.sql()} as t + select * from \${visitors.sql()} as t WHERE \${FILTER_PARAMS.ReferenceVisitors.createdAt.filter(\`(t.created_at + interval '28 day')\`)} AND \${FILTER_PARAMS.ReferenceVisitors.createdAt.filter((from, to) => \`(t.created_at + interval '28 day') >= \${from} AND (t.created_at + interval '28 day') <= \${to}\`)} \`, - + measures: { count: { type: 'count' }, - + googleSourcedCount: { type: 'count', filters: [{ @@ -477,7 +477,7 @@ describe('SQL Generation', () => { }] }, }, - + dimensions: { createdAt: { type: 'time', @@ -485,14 +485,14 @@ describe('SQL Generation', () => { } } }) - + cube('CubeWithVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongName', { sql: \` select * from cards \`, - + sqlAlias: 'cube_with_long_name', - + dataSource: 'oracle', measures: { @@ -501,12 +501,12 @@ describe('SQL Generation', () => { } } }); - + cube('compound', { sql: \` select * from compound_key_cards - \`, - + \`, + joins: { visitors: { relationship: 'belongsTo', diff --git a/packages/cubejs-schema-compiler/test/unit/transpilers.test.ts b/packages/cubejs-schema-compiler/test/unit/transpilers.test.ts index 2be0bee615642..56a53ee3d0a37 100644 --- a/packages/cubejs-schema-compiler/test/unit/transpilers.test.ts +++ b/packages/cubejs-schema-compiler/test/unit/transpilers.test.ts @@ -31,32 +31,6 @@ describe('Transpilers', () => { } }); - it('ValidationTranspiler', async () => { - const warnings: string[] = []; - - const { compiler } = prepareCompiler(` - cube(\`Test\`, { - sql: \`select * from test \${USER_CONTEXT.test1.filter('test1')}\`, - dimensions: { - test1: { - sql: 'test_1', - type: 'number' - }, - } - }); - `, { - errorReport: { - logger: (msg) => { - warnings.push(msg); - } - } - }); - - await compiler.compile(); - - expect(warnings[0]).toMatch(/Warning: USER_CONTEXT was deprecated in favor of SECURITY_CONTEXT. in main.js/); - }); - it('CubePropContextTranspiler', async () => { const { compiler } = prepareCompiler(` let { securityContext } = COMPILE_CONTEXT;