/* * Copyright (c) 2020 Huawei Technologies Co.,Ltd. * * openGauss is licensed under Mulan PSL v2. * You can use this software according to the terms and conditions of the Mulan PSL v2. * You may obtain a copy of Mulan PSL v2 at: * * http://license.coscl.org.cn/MulanPSL2 * * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PSL v2 for more details. * --------------------------------------------------------------------------------------- * * vectorbatch.inl * Core data structure template implementation for vEngine * * IDENTIFICATION * src/include/vecexecutor/vectorbatch.inl * * --------------------------------------------------------------------------------------- */ #ifndef VECTORBATCH_INL #define VECTORBATCH_INL /* * @Description: If we call original Pack func to pack data. * There are unnecessarily operations that all column data will be moved. * An optimization is using OptimizePack func to move specific column data that we want. * @in sel - flag which row we should move. * @in Copyvars - flag which column we should move. * @template copyMatch - copy match pattern which always true. * @template hasSysCol - whether has System column data need to move. */ template void VectorBatch::OptimizePackT(_in_ const bool * sel, _in_ List * CopyVars) { int i, j, writeIdx = 0; ScalarVector *pColumns = m_arr; int cRows = m_rows; int cColumns = m_cols; ScalarValue *pValues = NULL; uint8* pFlag = NULL; errno_t rc = EOK; Assert (IsValid()); // Copy all values what we need indeed instead of copy whole table. // for (i = 0; i < cRows; i++) { bool curSel = *sel ++; curSel = copyMatch ?curSel:!curSel; if (curSel) { if (i != writeIdx) { Assert (i > writeIdx); /* * If we call original Pack func to pack data. * There are unnecessarily operations that all column data will be moved. * An optimization is using OptimizePack func to move specific column data that we want. */ ListCell *var = NULL; foreach (var, CopyVars) { int k = lfirst_int(var) - 1; pValues = pColumns[k].m_vals; pFlag = pColumns[k].m_flag; pValues[writeIdx] = pValues[i]; pFlag[writeIdx] = pFlag[i]; } if(hasSysCol) { Assert(m_sysColumns != NULL); for(j = 0 ; j < m_sysColumns->sysColumns; j++) { //sys column do not need null flag pValues = m_sysColumns->m_ppColumns[j].m_vals; pValues[writeIdx] = pValues[i]; } } } writeIdx ++; } } for (j = 0; j < cColumns; j++) { pColumns[j].m_rows = writeIdx; } m_rows = writeIdx; Assert(m_rows >= 0 && m_rows <= BatchMaxSize); rc = memset_s(m_sel, BatchMaxSize * sizeof(bool), true, m_rows * sizeof(bool)); securec_check(rc,"\0","\0"); Assert (IsValid()); } /* * @Description: If we call original Pack func to pack data. * There are unnecessarily operations that all column data will be moved. * An optimization is using OptimizePackTForLateRead func to move specific column data * that we want in later read situation. * @in sel - flag which row we should move. * @in lateVars - flag which column we should move in late read. * @in ctidColIdx - flag which ctid column data. * @template copyMatch - copy match pattern which always true. * @template hasSysCol - whether has System column data need to move. */ template void VectorBatch::OptimizePackTForLateRead(_in_ const bool * sel, _in_ List * lateVars, int ctidColIdx) { int i, j, k, writeIdx = 0; ScalarVector *pColumns = m_arr; int cRows = m_rows; int cColumns = m_cols; ScalarValue *pValues = NULL; uint8* pFlag = NULL; errno_t rc = EOK; Assert (IsValid()); // Copy all values what we need indeed instead of copy whole table. // for (i = 0; i < cRows; i++) { bool curSel = *sel ++; curSel = copyMatch ?curSel:!curSel; if (curSel) { if (i != writeIdx) { Assert (i > writeIdx); /* * If we call original Pack func to pack data. * There are unnecessarily operations that all column data will be moved. * An optimization is using OptimizePack func to move specific column data that we want. */ ListCell *var = NULL; foreach (var, lateVars) { k = lfirst_int(var) - 1; pValues = pColumns[k].m_vals; pFlag = pColumns[k].m_flag; pValues[writeIdx] = pValues[i]; pFlag[writeIdx] = pFlag[i]; } k = ctidColIdx; pValues = pColumns[k].m_vals; pFlag = pColumns[k].m_flag; pValues[writeIdx] = pValues[i]; pFlag[writeIdx] = pFlag[i]; if(hasSysCol) { Assert(m_sysColumns != NULL); for(j = 0 ; j < m_sysColumns->sysColumns; j++) { //sys column do not need null flag pValues = m_sysColumns->m_ppColumns[j].m_vals; pValues[writeIdx] = pValues[i]; } } } writeIdx ++; } } for (j = 0; j < cColumns; j++) { pColumns[j].m_rows = writeIdx; } m_rows = writeIdx; Assert(m_rows >= 0 && m_rows <= BatchMaxSize); rc = memset_s(m_sel, BatchMaxSize * sizeof(bool), true, m_rows * sizeof(bool)); securec_check(rc,"\0","\0"); Assert (IsValid()); } template void VectorBatch::PackT (_in_ const bool *sel) { int i, j, writeIdx = 0; ScalarVector *pColumns = m_arr; int cRows = m_rows; int cColumns = m_cols; ScalarValue *pValues = NULL; uint8* pFlag = NULL; errno_t rc = EOK; Assert (IsValid()); // Copy all values // for (i = 0; i < cRows; i++) { bool curSel = *sel ++; curSel = copyMatch ?curSel:!curSel; if (curSel) { if (i != writeIdx) { Assert (i > writeIdx); for (j = 0; j < cColumns; j++) { pValues = pColumns[j].m_vals; pFlag = pColumns[j].m_flag; pValues[writeIdx] = pValues[i]; pFlag[writeIdx] = pFlag[i]; } if(hasSysCol) { Assert(m_sysColumns != NULL); for(j = 0 ; j < m_sysColumns->sysColumns; j++) { //sys column do not need null flag pValues = m_sysColumns->m_ppColumns[j].m_vals; pValues[writeIdx] = pValues[i]; } } } writeIdx ++; } } // Restore constant columns // for (j = 0; j < cColumns; j++) { pColumns[j].m_rows = writeIdx; } m_rows = writeIdx; Assert(m_rows >= 0 && m_rows <= BatchMaxSize); rc = memset_s(m_sel, BatchMaxSize * sizeof(bool), true, m_rows * sizeof(bool)); securec_check(rc,"\0","\0"); Assert (IsValid()); } #endif