This is an automated email from the ASF dual-hosted git repository.
liyang pushed a commit to branch kylin5
in repository https://gitbox.apache.org/repos/asf/kylin.git
The following commit(s) were added to refs/heads/kylin5 by this push:
new 16f8da9071 KYLIN-5822,support history table adds left-closed and
right-closed time interval
16f8da9071 is described below
commit 16f8da90718a2104729fb2a0c8d3cf61b1f8617f
Author: huangchunyan <[email protected]>
AuthorDate: Sat Apr 6 16:31:37 2024 +0800
KYLIN-5822,support history table adds left-closed and right-closed time
interval
---
.../components/setting/SettingAdvanced/locales.js | 6 +-
.../ModelList/Components/ModelTitleDescription.vue | 118 ++++++++++-----------
.../studio/StudioModel/ModelList/locales.js | 2 +-
.../studio/StudioModel/TableJoinModal/index.vue | 75 ++++++-------
.../studio/StudioModel/TableJoinModal/locales.js | 2 +-
5 files changed, 95 insertions(+), 108 deletions(-)
diff --git a/kystudio/src/components/setting/SettingAdvanced/locales.js
b/kystudio/src/components/setting/SettingAdvanced/locales.js
index 121517fd63..1c38df5169 100644
--- a/kystudio/src/components/setting/SettingAdvanced/locales.js
+++ b/kystudio/src/components/setting/SettingAdvanced/locales.js
@@ -51,9 +51,9 @@ export default {
confirmOpenTip: 'Do you want to continue?',
SCD2Settings: 'Support History table',
nonEqualJoin: 'Show non-equal join conditions for History table',
- noEqualDecription: 'With this switch ON, you may use the history table for
slowly changing dimension (as was): Non-equal join conditions (≥, <) could be
used for modeling, building and queries. ',
+ noEqualDecription: 'With this switch ON, you may use the history table for
slowly changing dimension (as was): Non-equal join conditions could be used for
modeling, building and queries. ',
confirmOpen: 'Turn On',
- closeSCDTip: 'With this switch OFF, non-equal join conditions (≥, <)
couldn\'t be used when editing model. The following models will go offline
automatically as they include non-equal join conditions:',
+ closeSCDTip: 'With this switch OFF, non-equal join conditions couldn\'t be
used when editing model. The following models will go offline automatically as
they include non-equal join conditions:',
closeSCDTip1: 'To make these models online, please delete the non-equal
join conditions, or turn this switch ON. Do you want to continue?',
confirmClose: 'Turn Off',
mulPartitionSettings: 'Multilevel Partitioning',
@@ -63,7 +63,7 @@ export default {
openMulPartitionTip: 'Please note that this feature is still in BETA
phase. Potential risks or known limitations might exist. Check ',
openMulPartitionTip1: ' for details.',
closeMulPartitionSetting: 'Turn Off Multilevel Partitioning',
- closeMulPartitionTip: 'With this switch OFF, multilevel partitioning
couldn’t be used. The following models would go offline automatically as they
used multilevel partitioning:',
+ closeMulPartitionTip: 'With this switch OFF, multilevel partitioning
couldn\'t be used. The following models would go offline automatically as they
used multilevel partitioning:',
closeMulPartitionTip1: 'To make these models online, please delete all
subpartitions, or turn this switch ON. Do you want to continue?',
snapshotTitle: 'Snapshot Management',
snapshotManagment: 'Support Snapshot Management',
diff --git
a/kystudio/src/components/studio/StudioModel/ModelList/Components/ModelTitleDescription.vue
b/kystudio/src/components/studio/StudioModel/ModelList/Components/ModelTitleDescription.vue
index b66af1b080..71390cda59 100644
---
a/kystudio/src/components/studio/StudioModel/ModelList/Components/ModelTitleDescription.vue
+++
b/kystudio/src/components/studio/StudioModel/ModelList/Components/ModelTitleDescription.vue
@@ -1,64 +1,64 @@
<template>
- <div class="model-alias-label" v-if="modelData">
- <div class="alias">
- <el-popover
- ref="statusPopover"
- popper-class="status-tooltip"
- placement="top-start"
- trigger="hover"
- :disabled="!modelData.status"
- >
- <span v-html="$t('modelStatus_c')" />
- <span>{{modelData.status}}</span>
- <div v-if="modelData.status === 'WARNING' &&
modelData.empty_indexes_count">{{$t('emptyIndexTips')}}</div>
- <div v-if="modelData.status === 'WARNING' &&
(modelData.segment_holes && modelData.segment_holes.length &&
modelData.model_type === 'BATCH') || (modelData.batch_segment_holes &&
modelData.batch_segment_holes.length && modelData.model_type === 'HYBRID')">
- <span>{{modelData.model_type === 'HYBRID' ?
$t('modelSegmentHoleTips1') : $t('modelSegmentHoleTips')}}</span><span
- v-if="!['modelEdit'].includes(source)"
- style="color:#0988DE;cursor: pointer;"
- @click="autoFix(modelData.alias, modelData.model_type ===
'HYBRID' ? modelData.batch_id : modelData.uuid, modelData.model_type ===
'HYBRID' ? modelData.batch_segment_holes :
modelData.segment_holes)">{{$t('seeDetail')}}</span>
+ <div class="model-alias-label" v-if="modelData">
+ <div class="alias">
+ <el-popover
+ ref="statusPopover"
+ popper-class="status-tooltip"
+ placement="top-start"
+ trigger="hover"
+ :disabled="!modelData.status"
+ >
+ <span v-html="$t('modelStatus_c')" />
+ <span>{{modelData.status}}</span>
+ <div v-if="modelData.status === 'WARNING' &&
modelData.empty_indexes_count">{{$t('emptyIndexTips')}}</div>
+ <div v-if="modelData.status === 'WARNING' && (modelData.segment_holes
&& modelData.segment_holes.length && modelData.model_type === 'BATCH') ||
(modelData.batch_segment_holes && modelData.batch_segment_holes.length &&
modelData.model_type === 'HYBRID')">
+ <span>{{modelData.model_type === 'HYBRID' ?
$t('modelSegmentHoleTips1') : $t('modelSegmentHoleTips')}}</span><span
+ v-if="!['modelEdit'].includes(source)"
+ style="color:#0988DE;cursor: pointer;"
+ @click="autoFix(modelData.alias, modelData.model_type === 'HYBRID'
? modelData.batch_id : modelData.uuid, modelData.model_type === 'HYBRID' ?
modelData.batch_segment_holes :
modelData.segment_holes)">{{$t('seeDetail')}}</span>
+ </div>
+ <div v-if="modelData.status === 'WARNING' && (modelData.segment_holes
&& modelData.segment_holes.length && modelData.model_type !== 'BATCH')">
+ <span>{{$t('modelSegmentHoleTips2')}}</span>
+ </div>
+ <div v-if="modelData.status === 'WARNING' &&
modelData.inconsistent_segment_count">
+ <span>{{$t('modelMetadataChangedTips')}}</span><span
+ v-if="!['modelEdit'].includes(source)"
+ style="color:#0988DE;cursor: pointer;"
+ @click="openComplementSegment(modelData,
true)">{{$t('seeDetail')}}</span>
+ </div>
+ <div v-if="modelData.status === 'OFFLINE' &&
modelData.forbidden_online">
+ <span>{{$t('SCD2ModalOfflineTip')}}</span>
+ </div>
+ <div v-if="modelData.status === 'OFFLINE' && !modelData.has_segments">
+ <span>{{$t('noSegmentOnlineTip')}}</span>
+ </div>
+ <div v-if="modelData.status === 'OFFLINE' &&
!$store.state.project.multi_partition_enabled &&
modelData.multi_partition_desc">
+ <span>{{$t('multilParTip')}}</span>
+ </div>
+ </el-popover>
+ <el-popover
+ ref="titlePopover"
+ placement="top-start"
+ width="250"
+ trigger="hover"
+ popper-class="title-popover-layout"
+ >
+ <div class="title-popover">
+ <p class="title ksd-mb-20">{{modelData.alias || modelData.name}}</p>
+ <div :class="['label', {'en': $lang === 'en'}]">
+ <div class="group ksd-mb-8" v-if="!onlyShowModelName"><span
class="title">{{$t('kylinLang.model.ownerGrid')}}</span><span
class="item">{{modelData.owner}}</span></div>
+ <div class="group"><span
class="title">{{$t('description')}}</span><span
class="item">{{modelData.description || '-'}}</span></div>
</div>
- <div v-if="modelData.status === 'WARNING' &&
(modelData.segment_holes && modelData.segment_holes.length &&
modelData.model_type !== 'BATCH')">
- <span>{{$t('modelSegmentHoleTips2')}}</span>
- </div>
- <div v-if="modelData.status === 'WARNING' &&
modelData.inconsistent_segment_count">
- <span>{{$t('modelMetadataChangedTips')}}</span><span
- v-if="!['modelEdit'].includes(source)"
- style="color:#0988DE;cursor: pointer;"
- @click="openComplementSegment(modelData,
true)">{{$t('seeDetail')}}</span>
- </div>
- <div v-if="modelData.status === 'OFFLINE' &&
modelData.forbidden_online">
- <span>{{$t('SCD2ModalOfflineTip')}}</span>
- </div>
- <div v-if="modelData.status === 'OFFLINE' &&
!modelData.has_segments">
- <span>{{$t('noSegmentOnlineTip')}}</span>
- </div>
- <div v-if="modelData.status === 'OFFLINE' &&
!$store.state.project.multi_partition_enabled &&
modelData.multi_partition_desc">
- <span>{{$t('multilParTip')}}</span>
- </div>
- </el-popover>
- <el-popover
- ref="titlePopover"
- placement="top-start"
- width="250"
- trigger="hover"
- popper-class="title-popover-layout"
- >
- <div class="title-popover">
- <p class="title ksd-mb-20">{{modelData.alias ||
modelData.name}}</p>
- <div :class="['label', {'en': $lang === 'en'}]">
- <div class="group ksd-mb-8" v-if="!onlyShowModelName"><span
class="title">{{$t('kylinLang.model.ownerGrid')}}</span><span
class="item">{{modelData.owner}}</span></div>
- <div class="group"><span
class="title">{{$t('description')}}</span><span
class="item">{{modelData.description || '-'}}</span></div>
- </div>
- </div>
- </el-popover>
- <span :class="['filter-status', (modelData.status || 'OFFLINE')]"
v-popover:statusPopover v-if="!onlyShowModelName"></span>
- <span class="model-alias-title" @mouseenter.prevent
v-popover:titlePopover>{{modelData.alias || modelData.name}}</span>
- </div>
- <el-tooltip class="last-modified-tooltip" effect="dark"
:content="`${$t('dataLoadTime')}${modelData.gmtTime}`" placement="bottom"
:disabled="hideTimeTooltip" v-if="!onlyShowModelName">
- <span>{{getLastTime}}</span>
- </el-tooltip>
+ </div>
+ </el-popover>
+ <span :class="['filter-status', (modelData.status || 'OFFLINE')]"
v-popover:statusPopover v-if="!onlyShowModelName"></span>
+ <span class="model-alias-title" @mouseenter.prevent
v-popover:titlePopover>{{modelData.alias || modelData.name}}</span>
</div>
- </template>
+ <el-tooltip class="last-modified-tooltip" effect="dark"
:content="`${$t('dataLoadTime')}${modelData.gmtTime}`" placement="bottom"
:disabled="hideTimeTooltip" v-if="!onlyShowModelName">
+ <span>{{getLastTime}}</span>
+ </el-tooltip>
+ </div>
+</template>
<script>
import Vue from 'vue'
@@ -96,7 +96,7 @@
seeDetail: 'View Details',
description: 'Description',
dataLoadTime: 'Last Updated Time: ',
- SCD2ModalOfflineTip: 'This model includes non-equal join conditions
(≥, <), which are not supported at the moment. Please delete those join
conditions, or turn on `Support History table` in project settings.',
+ SCD2ModalOfflineTip: 'This model includes non-equal join conditions,
which are not supported at the moment. Please delete those join conditions, or
turn on `Support History table` in project settings.',
noSegmentOnlineTip: 'This model can\'t go online as it doesn\'t have
segments. Models with no segment couldn\'t serve queries. Please add a
segment.',
multilParTip: 'This model used multilevel partitioning, which are not
supported at the moment. Please set subpartition as \'None\' in model partition
dialog, or turn on \'Multilevel Partitioning\' in project settings.',
lastUpdate: 'Last Updated: '
diff --git a/kystudio/src/components/studio/StudioModel/ModelList/locales.js
b/kystudio/src/components/studio/StudioModel/ModelList/locales.js
index c73e7e054c..51a3b5fdba 100644
--- a/kystudio/src/components/studio/StudioModel/ModelList/locales.js
+++ b/kystudio/src/components/studio/StudioModel/ModelList/locales.js
@@ -93,7 +93,7 @@ export default {
buildIndex: 'Build Index',
batchBuildSubTitle: 'Please choose which data ranges you\'d like to build
with the added indexes.',
refrashWarningSegment: 'Only ONLINE segments could be refreshed',
- closeSCD2ModalOnlineTip: 'This model can\'t go online as it includes
non-equal join conditions(≥, <). Please delete those join conditions, or turn
on `Support History table` in project settings.',
+ closeSCD2ModalOnlineTip: 'This model can\'t go online as it includes
non-equal join conditions. Please delete those join conditions, or turn on
`Support History table` in project settings.',
storageTip: 'Calculates the amount of data built in this model',
subPartitionValuesManage: 'Manage Sub-Partition Values',
segmentHoletips: 'There exists a gap in the segment range, and the data of
this range cannot be queried. Please confirm whether to add the following
segments to fix.',
diff --git
a/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
b/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
index 6f9b978861..23f3d4011e 100644
--- a/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
+++ b/kystudio/src/components/studio/StudioModel/TableJoinModal/index.vue
@@ -154,7 +154,9 @@ export default class TableJoinModal extends Vue {
columnsLinkKind = [
{label: '=', value: 'EQUAL'},
{label: '>=', value: 'GREATER_THAN_OR_EQUAL'},
- {label: '<', value: 'LESS_THAN'}
+ {label: '<', value: 'LESS_THAN'},
+ {label: '>', value: 'GREATER_THAN'},
+ {label: '<=', value: 'LESS_THAN_OR_EQUAL'}
]
columnJoinType = 0
isErrorValue = []
@@ -455,8 +457,10 @@ export default class TableJoinModal extends Vue {
this.isErrorValue = []
this.errorFlag = []
let joins = joinColumns.foreign_key.map((item, index) => ({fk: item, op:
joinColumns.op[index], pk: joinColumns.primary_key[index], index,
joinExpression: `${item}&${joinColumns.primary_key[index]}`}))
- let greater_than = joins.filter(it => it.op === 'GREATER_THAN_OR_EQUAL' &&
it.fk && it.pk)
+ let greater_than_or_equal = joins.filter(it => it.op ===
'GREATER_THAN_OR_EQUAL' && it.fk && it.pk)
let less_than = joins.filter(it => it.op === 'LESS_THAN' && it.fk && it.pk)
+ let less_than_or_equal = joins.filter(it => it.op === 'LESS_THAN_OR_EQUAL'
&& it.fk && it.pk)
+ let greater_than = joins.filter(it => it.op === 'GREATER_THAN' && it.fk &&
it.pk)
// let equals = joins.filter(it => it.op === 'EQUAL' && it.fk && it.pk)
// 两张表仅可使用同一关联关系一次
const pAlias = this.form.tables[this.form.pid].name.split('.')[1]
@@ -472,43 +476,6 @@ export default class TableJoinModal extends Vue {
this.isErrorValue.push(4)
flag = false
}
- // let correctTableName = (pid, fid) => {
- // return {
- // pTable: this.form.tables[pid].name.replace(/^(\w+)\./, ''),
- // tTable: this.form.tables[fid].name.replace(/^(\w+)\./, '')
- // }
- // }
- // let fk = joinColumns.foreign_key.map(it => it.replace(/(\w+)\./,
`${correctTableName(this.form.pid, this.form.fid).tTable}.`))
- // let pk = joinColumns.primary_key.map(it => it.replace(/(\w+)\./,
`${correctTableName(this.form.pid, this.form.fid).pTable}.`))
- // let combination = fk.map((item, index) => `${item}&${pk[index]}`)
- // let joinInfoHistory =
Object.keys(this.form.modelInstance.linkUsedColumns).filter(it =>
it.indexOf(this.form.fid) >= 0 && it !== `${this.form.pid}${this.form.fid}`)
- // if (joinInfoHistory.length) {
- // let tables = []
- // joinInfoHistory.map(item =>
this.form.modelInstance.linkUsedColumns[item]).forEach((list, idx) => {
- // let joinId = joinInfoHistory[idx]
- // let start = joinId.indexOf(this.form.fid)
- // let uid = []
- // if (start === 0) {
- // uid = [joinId.slice(0, this.form.fid.length),
joinId.slice(this.form.fid.length, joinId.length)]
- // } else {
- // uid = [joinId.slice(joinId.length - this.form.fid.length,
joinId.length), joinId.slice(0, joinId.length - this.form.fid.length)]
- // }
- // for (let i = 0; i <= list.length / 2 - 1; i++) {
- // tables.push(`${list[i + list.length / 2].replace(/(\w+)\./,
`${correctTableName(uid[1], uid[0]).tTable}.`)}&${list[i].replace(/(\w+)\./,
`${correctTableName(uid[1], uid[0]).pTable}.`)}`)
- // }
- // })
- // if (tables.length) {
- // let cludesIndex = []
- // combination.forEach((v, index) => {
- // tables.includes(v) && cludesIndex.push(index)
- // })
- // if (cludesIndex.length) {
- // this.errorFlag = [...this.errorFlag, ...cludesIndex]
- // this.isErrorValue.push(4)
- // flag = false
- // }
- // }
- // }
// 至少有一个equal连接关系
if (!joinColumns.op.includes('EQUAL')) {
this.isErrorValue.push(3)
@@ -525,21 +492,41 @@ export default class TableJoinModal extends Vue {
// 连接关系 >= 和 < 成对出现, 且位于中间的列必须一致(此处判断放在最后处理)
let checkFun = () => {
let fl = true
- let firstV = greater_than.shift(0)
+ let firstV = greater_than_or_equal.shift(0)
while (firstV) {
- let idx = less_than.findIndex(it => it.fk === firstV.fk)
+ let idx = less_than.findIndex(it => it.fk === firstV.fk || it.pk ===
firstV.pk)
+ let idx2 = less_than_or_equal.findIndex(it => it.fk === firstV.fk ||
it.pk === firstV.pk)
if (idx >= 0) {
less_than.splice(idx, 1)
+ } else if (idx2 >= 0) {
+ less_than_or_equal.splice(idx2, 1)
} else {
this.errorFlag.push(firstV.index)
fl = false
}
- firstV = greater_than.shift(0)
+ firstV = greater_than_or_equal.shift(0)
}
- if (less_than.length) {
- this.errorFlag = [...this.errorFlag, ...less_than.map(it => it.index)]
+ if (firstV && (less_than.length || less_than_or_equal.length)) {
+ this.errorFlag = [...this.errorFlag, ...less_than.map(it => it.index),
...less_than_or_equal.map(it => it.index)]
fl = false
}
+ if (fl) {
+ let firstV2 = greater_than.shift(0)
+ while (firstV2) {
+ let idx3 = less_than_or_equal.findIndex(it => it.fk === firstV2.fk
|| it.pk === firstV2.pk)
+ if (idx3 >= 0) {
+ less_than_or_equal.splice(idx3, 1)
+ } else {
+ this.errorFlag.push(firstV2.index)
+ fl = false
+ }
+ firstV2 = greater_than.shift(0)
+ }
+ if (less_than_or_equal.length) {
+ this.errorFlag = [...this.errorFlag, ...less_than_or_equal.map(it =>
it.index)]
+ fl = false
+ }
+ }
return fl
}
if (!checkFun()) {
diff --git
a/kystudio/src/components/studio/StudioModel/TableJoinModal/locales.js
b/kystudio/src/components/studio/StudioModel/TableJoinModal/locales.js
index 0f5cd1b9c1..572ef3f492 100644
--- a/kystudio/src/components/studio/StudioModel/TableJoinModal/locales.js
+++ b/kystudio/src/components/studio/StudioModel/TableJoinModal/locales.js
@@ -11,7 +11,7 @@ export default {
joinErrorNotice: 'The join condition can\'t be saved. Please modify and
try again.',
details: 'View Details',
notice1: 'Can\'t define multiple join conditions for the same columns',
- notice2: 'Join relationship ≥ and < must be used in pairs, and same column
must be joint in both conditions',
+ notice2: 'Non-equal join condition only supports the following three
pairs:1) >= and < ,2)>= and <=,3)> and<=, and same column must be joint in both
conditions',
notice3: 'Join relationship for columns should include at least one
equal-join condition (=)',
notice4: 'Two tables could only be joined by the same condition for one
time',
manyToOne: 'One-to-One or Many-to-One',