IDEMPIERE-5943 Implement table partitioning support (#2145)

* IDEMPIERE-5943 Implement table partitioning support

Co-authored-by: etantg <etan@trekglobal.com>
This commit is contained in:
hengsin 2023-12-20 14:10:04 +08:00 committed by GitHub
parent 3b8a15ee84
commit 7878721bf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 4248 additions and 8 deletions

View File

@ -0,0 +1,256 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312041549_IDEMPIERE-5943.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Dec 4, 2023, 3:49:42 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203881,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:49:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:49:41','YYYY-MM-DD HH24:MI:SS'),100,'IsPartition','Partition','Partition','D','71a4c045-f75b-435e-997f-ca453554d40f')
;
-- Dec 4, 2023, 3:51:05 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216282,0,'Partition',100,'IsPartition','N',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:51:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:51:04','YYYY-MM-DD HH24:MI:SS'),100,203881,'Y','N','D','N','N','N','Y','fae626e9-69df-411a-8d1d-a8e59b3b48df','Y',0,'N','N','N')
;
-- Dec 4, 2023, 3:51:39 PM MYT
UPDATE AD_Column SET IsMandatory='Y',Updated=TO_TIMESTAMP('2023-12-04 15:51:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216282
;
-- Dec 4, 2023, 3:51:47 PM MYT
ALTER TABLE AD_Table ADD IsPartition CHAR(1) DEFAULT 'N' CHECK (IsPartition IN ('Y','N')) NOT NULL
;
-- Dec 4, 2023, 3:52:20 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203882,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:52:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:52:19','YYYY-MM-DD HH24:MI:SS'),100,'PartitioningMethod','Partitioning Method','Partitioning Method','D','5dc2d9dd-1e38-4985-a741-2f779891e4df')
;
-- Dec 4, 2023, 3:53:10 PM MYT
INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU,ShowInactive) VALUES (200261,'AD_Table PartitioningMethod','L',0,0,'Y',TO_TIMESTAMP('2023-12-04 15:53:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:53:09','YYYY-MM-DD HH24:MI:SS'),100,'D','N','81b6431b-0afa-49bc-b5fe-be9a7b2481cf','N')
;
-- Dec 4, 2023, 3:53:22 PM MYT
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200684,'Range',200261,'R',0,0,'Y',TO_TIMESTAMP('2023-12-04 15:53:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:53:22','YYYY-MM-DD HH24:MI:SS'),100,'D','d8a5f9ab-574e-4926-93eb-e4a392c36e3c')
;
-- Dec 4, 2023, 3:53:33 PM MYT
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200685,'List',200261,'L',0,0,'Y',TO_TIMESTAMP('2023-12-04 15:53:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:53:32','YYYY-MM-DD HH24:MI:SS'),100,'D','d909c15e-9b97-4171-87bb-7de77cee4eb8')
;
-- Dec 4, 2023, 3:55:31 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,MandatoryLogic,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216283,0,'Partitioning Method',101,'PartitioningMethod',2,'N','N','N','N','N',0,'N',17,200261,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:55:30','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:55:30','YYYY-MM-DD HH24:MI:SS'),100,203882,'Y','N','D','N','N','@IsPartition@=''Y''','N','Y','b67a043a-019a-479d-81c4-5439a3447aaa','Y',0,'N','N','N')
;
-- Dec 4, 2023, 3:55:42 PM MYT
ALTER TABLE AD_Column ADD PartitioningMethod VARCHAR2(2 CHAR) DEFAULT NULL
;
-- Dec 4, 2023, 3:56:10 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203883,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:56:10','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:56:10','YYYY-MM-DD HH24:MI:SS'),100,'RangePartitionInterval','Range Partition Interval','Range Partition Interval','D','f14b1920-8c8f-4cb5-9f85-a579d854625d')
;
-- Dec 4, 2023, 3:59:04 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203884,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:59:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:59:04','YYYY-MM-DD HH24:MI:SS'),100,'CreatePartition','Create/update partition','Create/update partition','D','356bc70e-12d7-478b-a70f-24adb47024af')
;
-- Dec 4, 2023, 4:02:43 PM MYT
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,ShowHelp,AD_Process_UU,AllowMultipleExecution) VALUES (200157,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:02:42','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:02:42','YYYY-MM-DD HH24:MI:SS'),100,'Create/update partition','N','AD_Table CreatePartition','N','org.idempiere.tablepartition.process.CreatePartition','4','D',0,0,'N','Y','5f9a2aa4-a18d-4629-b613-15d2436c4898','NA')
;
-- Dec 4, 2023, 4:04:16 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,AD_Process_ID,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216285,0,'Create/update partition',100,'CreatePartition',1,'N','N','N','N','N',0,'N',28,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:04:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:04:15','YYYY-MM-DD HH24:MI:SS'),100,203884,'Y',200157,'N','D','N','N','N','Y','65d73bf3-bf25-45dd-aa14-662f511fccb2','Y',0,'Y','N','N')
;
-- Dec 4, 2023, 4:04:33 PM MYT
ALTER TABLE AD_Table ADD CreatePartition CHAR(1) DEFAULT NULL
;
-- Dec 4, 2023, 4:05:45 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203885,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:05:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:05:44','YYYY-MM-DD HH24:MI:SS'),100,'IsPartitionKey','Partition Key','Partition Key','D','bac735c9-addb-4dfa-81d7-4506cbad6ed0')
;
-- Dec 4, 2023, 4:06:12 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216286,0,'Partition Key',101,'IsPartitionKey','''N''',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:06:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:06:11','YYYY-MM-DD HH24:MI:SS'),100,203885,'Y','N','D','N','N','N','Y','248d95b0-6318-4821-9053-fa6138d8049b','Y',0,'N','N','N')
;
-- Dec 4, 2023, 4:06:19 PM MYT
ALTER TABLE AD_Column ADD IsPartitionKey CHAR(1) DEFAULT 'N' CHECK (IsPartitionKey IN ('Y','N')) NOT NULL
;
-- Dec 4, 2023, 4:08:38 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203886,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:08:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:08:38','YYYY-MM-DD HH24:MI:SS'),100,'SeqNoPartition','Partition Key Sequence','Partition Key Sequence','D','d9593a7f-cc70-4403-834e-0dca74044fdb')
;
-- Dec 4, 2023, 4:21:40 PM MYT
INSERT INTO AD_Table (AD_Table_ID,Name,TableName,LoadSeq,AccessLevel,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSecurityEnabled,IsDeleteable,IsHighVolume,IsView,EntityType,ImportTable,IsChangeLog,ReplicationType,CopyColumnsFromTable,IsCentrallyMaintained,AD_Table_UU,Processing,DatabaseViewDrop,CopyComponentsFromView,CreateWindowFromTable,IsShowInDrillOptions) VALUES (200411,'Table Partition','AD_TablePartition',0,'4',0,0,'Y',TO_TIMESTAMP('2023-12-04 16:21:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:21:40','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','N','D','N','Y','L','N','Y','b778984a-9a96-4db4-a54f-8f47e6583f5e','N','N','N','N','N')
;
-- Dec 4, 2023, 4:21:41 PM MYT
INSERT INTO AD_Sequence (Name,CurrentNext,IsAudited,StartNewYear,Description,IsActive,IsTableID,AD_Client_ID,AD_Org_ID,Created,CreatedBy,Updated,UpdatedBy,AD_Sequence_ID,IsAutoSequence,StartNo,IncrementNo,CurrentNextSys,AD_Sequence_UU) VALUES ('AD_TablePartition',1000000,'N','N','Table AD_TablePartition','Y','Y',0,0,TO_TIMESTAMP('2023-12-04 16:21:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:21:41','YYYY-MM-DD HH24:MI:SS'),100,200482,'Y',1000000,1,200000,'25e2994d-bed5-4a71-a6da-7b1b96c6cb77')
;
-- Dec 4, 2023, 4:25:41 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,AD_Val_Rule_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216287,0,'Tenant','Tenant for this installation.','A Tenant is a company or a legal entity. You cannot share data between Tenants.',200411,129,'AD_Client_ID','@#AD_Client_ID@',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:39','YYYY-MM-DD HH24:MI:SS'),100,102,'N','N','D','N','N','N','Y','8aa0a7f1-d581-4075-b7dd-229c81528e5f','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:25:42 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203887,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:42','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:42','YYYY-MM-DD HH24:MI:SS'),100,'AD_TablePartition_ID','Table Partition','Table Partition','D','1751f83e-723a-49a4-894d-eee7526a2878')
;
-- Dec 4, 2023, 4:25:43 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216289,0,'Table Partition',200411,'AD_TablePartition_ID',22,'Y','N','N','N','N',0,'N',13,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:41','YYYY-MM-DD HH24:MI:SS'),100,203887,'N','N','D','N','N','N','Y','2dca6112-15b8-4bdc-836d-29067967f910','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:45 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203888,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,'AD_TablePartition_UU','AD_TablePartition_UU','AD_TablePartition_UU','D','771b52d3-12ba-4c1f-b2ec-e1bfc4465173')
;
-- Dec 4, 2023, 4:25:45 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216291,0,'AD_TablePartition_UU',200411,'AD_TablePartition_UU',36,'N','N','N','N','N',0,'N',200231,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,203888,'N','N','D','N','N','N','Y','b28719af-aa1e-4461-8519-135684688bc0','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:46 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,AD_Val_Rule_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216292,0,'Organization','Organizational entity within tenant','An organization is a unit of your tenant or legal entity - examples are store, department. You can share data between organizations.',200411,104,'AD_Org_ID','@#AD_Org_ID@',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:45','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:45','YYYY-MM-DD HH24:MI:SS'),100,113,'N','N','D','N','N','N','Y','cbeed504-0d75-453b-8b85-07e7db4586ee','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:25:47 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216293,0,'Created','Date this record was created','The Created field indicates the date that this record was created.',200411,'Created','SYSDATE',7,'N','N','N','N','N',0,'N',16,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:46','YYYY-MM-DD HH24:MI:SS'),100,245,'N','N','D','N','N','N','Y','89ef8f7b-0f27-4314-a9c2-163d90e630fb','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:48 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216294,0,'Created By','User who created this records','The Created By field indicates the user who created this record.',200411,'CreatedBy',22,'N','N','N','N','N',0,'N',30,110,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:47','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:47','YYYY-MM-DD HH24:MI:SS'),100,246,'N','N','D','N','N','N','Y','2f778d0a-ba9d-437b-ad54-74e43bd80b4a','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:25:49 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216296,0,'Active','The record is active in the system','There are two methods of making records unavailable in the system: One is to delete the record, the other is to de-activate the record. A de-activated record is not available for selection, but available for reports.
There are two reasons for de-activating and not deleting records:
(1) The system requires the record for audit purposes.
(2) The record is referenced by other records. E.g., you cannot delete a Business Partner, if there are invoices for this partner record existing. You de-activate the Business Partner and prevent that this record is used for future entries.',200411,'IsActive','Y',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,348,'Y','N','D','N','N','N','Y','fc84d078-1b2c-4e8b-824d-bc22e45f0a7e','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:50 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216297,0,'Name','Alphanumeric identifier of the entity','The name of an entity (record) is used as an default search option in addition to the search key. The name is up to 60 characters in length.',200411,'Name',60,'N','N','Y','N','Y',0,'N',10,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,469,'Y','Y','D','N','N','N','Y','9682330b-98e7-4668-84f5-92e44e16b4cd','Y',20,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:51 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216298,0,'Updated','Date this record was updated','The Updated field indicates the date that this record was updated.',200411,'Updated','SYSDATE',7,'N','N','N','N','N',0,'N',16,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:50','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:50','YYYY-MM-DD HH24:MI:SS'),100,607,'N','N','D','N','N','N','Y','e8c449c5-674a-4482-baef-74dc7af4ae70','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:52 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216299,0,'Updated By','User who updated this records','The Updated By field indicates the user who updated this record.',200411,'UpdatedBy',22,'N','N','N','N','N',0,'N',30,110,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:51','YYYY-MM-DD HH24:MI:SS'),100,608,'N','N','D','N','N','N','Y','683a0936-b0f2-4283-9191-481832116399','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:30:01 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216300,0,'Table','Database Table information','The Database Table provides the information of the table definition',200411,'AD_Table_ID',10,'N','Y','Y','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:30:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:30:00','YYYY-MM-DD HH24:MI:SS'),100,126,'N','N','D','N','N','N','Y','a8c6c6c3-c965-4b34-a274-c3b7ec6d3240','Y',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:31:20 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203889,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:31:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:31:19','YYYY-MM-DD HH24:MI:SS'),100,'ExpressionPartition','Expression','SQL clause for partition','Expression','D','46974aa7-440e-4473-8092-cf80e3b98c2c')
;
-- Dec 4, 2023, 4:34:29 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216301,0,'Expression','SQL clause for partition',200411,'ExpressionPartition',250,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:34:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:34:29','YYYY-MM-DD HH24:MI:SS'),100,203889,'Y','N','D','N','N','N','Y','d90007d9-3737-4d8a-8acb-6beeec3fce2c','Y',0,'N','N','N')
;
-- Dec 4, 2023, 4:37:38 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208078,'IsPartition',100,216282,'Y',1,250,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 16:37:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:37:37','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','d0e6d1e0-96a6-4f3d-8747-061b28c0ef47','Y',210,2,2)
;
-- Dec 4, 2023, 4:37:40 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208081,'Create/update partition',100,216285,'Y',1,280,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 16:37:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:37:39','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','0ca9fea4-c0bf-4a97-b8a9-501667ce767c','Y',240,2,2)
;
-- Dec 4, 2023, 5:58:50 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y',Updated=TO_TIMESTAMP('2023-12-04 17:58:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208079
;
-- Dec 4, 2023, 6:02:19 PM MYT
UPDATE AD_Column SET IsToolbarButton='N',Updated=TO_TIMESTAMP('2023-12-04 18:02:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216285
;
-- Dec 4, 2023, 6:03:28 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y',Updated=TO_TIMESTAMP('2023-12-04 18:03:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208081
;
-- Dec 4, 2023, 6:06:42 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208082,'Partition Key',101,216286,'Y',1,530,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:06:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:06:41','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','f37e6afb-66b4-4fc4-96b6-411675c109a8','Y',480,2,2)
;
-- Dec 4, 2023, 6:08:21 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216302,0,'Partition Key Sequence',101,'SeqNoPartition',14,'N','N','N','N','N',0,'N',11,0,0,'Y',TO_TIMESTAMP('2023-12-04 18:08:20','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:08:20','YYYY-MM-DD HH24:MI:SS'),100,203886,'Y','N','D','N','N','N','Y','6fe55ecb-5be5-43bc-a347-15ba40b1e88e','Y',0,'N','N','N')
;
-- Dec 4, 2023, 6:08:28 PM MYT
ALTER TABLE AD_Column ADD SeqNoPartition NUMBER(10) DEFAULT NULL
;
-- Dec 4, 2023, 6:09:25 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208083,'Partition Key Sequence',101,216302,'Y',14,540,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:09:24','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:09:24','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','7f43d839-4d4c-46df-9bd4-5a564265a7f9','Y',490,2)
;
-- Dec 4, 2023, 6:10:12 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y',Updated=TO_TIMESTAMP('2023-12-04 18:10:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208082
;
-- Dec 4, 2023, 6:10:38 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y & @IsPartitionKey@=Y',Updated=TO_TIMESTAMP('2023-12-04 18:10:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208083
;
-- Dec 4, 2023, 6:31:40 PM MYT
UPDATE AD_Field SET XPosition=4,Updated=TO_TIMESTAMP('2023-12-04 18:31:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208083
;
-- Dec 4, 2023, 6:35:00 PM MYT
INSERT INTO AD_Tab (AD_Tab_ID,Name,AD_Window_ID,SeqNo,IsSingleRow,AD_Table_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,HasTree,IsInfoTab,IsTranslationTab,IsReadOnly,Processing,ImportFields,TabLevel,IsSortTab,EntityType,DisplayLogic,IsInsertRecord,IsAdvancedTab,AD_Tab_UU,TreeDisplayedOn,IsLookupOnlySelection,IsAllowAdvancedLookup,MaxQueryRecords) VALUES (200381,'Table Partition',100,120,'Y',200411,0,0,'Y',TO_TIMESTAMP('2023-12-04 18:34:59','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:34:59','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','Y','N','N',1,'N','D','@IsPartition@=''Y''','N','N','6eecaed6-a84a-4d43-adbc-954917c76d2a','B','N','Y',0)
;
-- Dec 4, 2023, 6:35:11 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (208084,'Tenant','Tenant for this installation.','A Tenant is a company or a legal entity. You cannot share data between Tenants.',200381,216287,'Y',22,10,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','40f081a2-c503-467c-926b-d963f7c01312','N',2)
;
-- Dec 4, 2023, 6:35:12 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsAllowCopy,IsDisplayedGrid,XPosition,ColumnSpan) VALUES (208085,'Organization','Organizational entity within tenant','An organization is a unit of your tenant or legal entity - examples are store, department. You can share data between organizations.',200381,216292,'Y',22,20,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','737d9a62-d5f2-412d-9a9a-420d2f32c06d','Y','N',4,2)
;
-- Dec 4, 2023, 6:35:13 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208086,'Table','Database Table information','The Database Table provides the information of the table definition',200381,216300,'Y',10,30,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:12','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:12','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','d2c0143c-2da2-43c5-8950-54c066f562a4','Y',10,2)
;
-- Dec 4, 2023, 6:35:14 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208087,'Name','Alphanumeric identifier of the entity','The name of an entity (record) is used as an default search option in addition to the search key. The name is up to 60 characters in length.',200381,216297,'Y',60,40,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:13','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','b0cbc492-2be7-49f3-ad7f-c553037c8d0d','Y',20,5)
;
-- Dec 4, 2023, 6:35:14 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (208088,'Table Partition',200381,216289,'N',22,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:14','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','4f8e1c9e-205a-43d6-884b-e8503eef6d86','N',2)
;
-- Dec 4, 2023, 6:35:16 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (208089,'AD_TablePartition_UU',200381,216291,'N',36,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:15','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','12666f96-7ead-472f-a9a0-b78ba5b5b30a','N',2)
;
-- Dec 4, 2023, 6:35:16 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208090,'Expression','SQL clause for partition',200381,216301,'Y',250,50,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','85314375-dd91-411e-b8fe-89649a84e039','Y',30,5)
;
-- Dec 4, 2023, 6:35:17 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208091,'Active','The record is active in the system','There are two methods of making records unavailable in the system: One is to delete the record, the other is to de-activate the record. A de-activated record is not available for selection, but available for reports.
There are two reasons for de-activating and not deleting records:
(1) The system requires the record for audit purposes.
(2) The record is referenced by other records. E.g., you cannot delete a Business Partner, if there are invoices for this partner record existing. You de-activate the Business Partner and prevent that this record is used for future entries.',200381,216296,'Y',1,60,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','aa8e85d5-3cc6-4cc7-ab6a-0c36b5f1a8ec','Y',40,2,2)
;
-- Dec 4, 2023, 6:37:58 PM MYT
UPDATE AD_Column SET IsMandatory='Y',Updated=TO_TIMESTAMP('2023-12-04 18:37:58','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216301
;
-- Dec 4, 2023, 6:38:11 PM MYT
UPDATE AD_Column SET IsUpdateable='N', FKConstraintName='ADTable_ADTablePartition', FKConstraintType='N',Updated=TO_TIMESTAMP('2023-12-04 18:38:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216300
;
-- Dec 4, 2023, 6:38:12 PM MYT
CREATE TABLE AD_TablePartition (AD_Client_ID NUMBER(10) DEFAULT NULL , AD_Org_ID NUMBER(10) DEFAULT NULL , AD_Table_ID NUMBER(10) NOT NULL, AD_TablePartition_ID NUMBER(10) DEFAULT NULL , AD_TablePartition_UU VARCHAR2(36 CHAR) DEFAULT NULL , Created DATE DEFAULT SYSDATE, CreatedBy NUMBER(10) DEFAULT NULL , ExpressionPartition VARCHAR2(250 CHAR) NOT NULL, IsActive CHAR(1) DEFAULT 'Y' CHECK (IsActive IN ('Y','N')), Name VARCHAR2(60 CHAR) NOT NULL, Updated DATE DEFAULT SYSDATE, UpdatedBy NUMBER(10) DEFAULT NULL , CONSTRAINT AD_TablePartition_Key PRIMARY KEY (AD_TablePartition_ID), CONSTRAINT AD_TablePartition_UU_idx UNIQUE (AD_TablePartition_UU))
;
-- Dec 4, 2023, 6:38:12 PM MYT
ALTER TABLE AD_TablePartition ADD CONSTRAINT ADTable_ADTablePartition FOREIGN KEY (AD_Table_ID) REFERENCES ad_table(ad_table_id) DEFERRABLE INITIALLY DEFERRED
;

View File

@ -0,0 +1,237 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312131039_IDEMPIERE-5943.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Dec 13, 2023, 10:39:08 AM MYT
UPDATE AD_Column SET DefaultValue='@SQL=SELECT COALESCE(MAX(SeqNoPartition),0)+10 AS DefaultValue FROM AD_Column WHERE AD_Table_ID=@AD_Table_ID@ AND IsActive=''Y'' AND IsPartitionKey=''Y''',Updated=TO_TIMESTAMP('2023-12-13 10:39:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216302
;
-- Dec 13, 2023, 10:41:20 AM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,MandatoryLogic,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml,IsPartitionKey,SeqNoPartition) VALUES (216304,0,'Range Partition Interval',101,'RangePartitionInterval',30,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_TIMESTAMP('2023-12-13 10:41:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 10:41:19','YYYY-MM-DD HH24:MI:SS'),100,203883,'Y','N','D','N','N','@IsPartition@=''Y'' & @PartitioningMethod@=''R''','N','Y','e8dff995-1857-4653-8aa2-18d6e89620fd','Y',0,'N','N','N','N','N',0)
;
-- Dec 13, 2023, 10:41:31 AM MYT
ALTER TABLE AD_Column ADD RangePartitionInterval VARCHAR2(30 CHAR) DEFAULT NULL
;
-- Dec 13, 2023, 10:42:52 AM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208093,'Range Partition Interval',101,216304,'Y',30,550,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-13 10:42:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 10:42:51','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','e4d0ddb5-cc5b-4969-96fd-718a759635ff','Y',500,2)
;
-- Dec 13, 2023, 10:44:43 AM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y & @IsPartitionKey@=Y & @PartitioningMethod@=R',Updated=TO_TIMESTAMP('2023-12-13 10:44:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208093
;
-- Dec 13, 2023, 10:54:43 AM MYT
UPDATE AD_Element SET Description='This is a partitioned table',Updated=TO_TIMESTAMP('2023-12-13 10:54:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203881
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Column SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203881
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, AD_Element_ID=203881 WHERE UPPER(ColumnName)='ISPARTITION' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203881 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_InfoColumn SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203881 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Field SET Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203881) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:02:03 AM MYT
UPDATE AD_Element SET Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.',Updated=TO_TIMESTAMP('2023-12-13 11:02:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203882
;
-- Dec 13, 2023, 11:02:03 AM MYT
UPDATE AD_Column SET ColumnName='PartitioningMethod', Name='Partitioning Method', Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.', Placeholder=NULL WHERE AD_Element_ID=203882
;
-- Dec 13, 2023, 11:02:04 AM MYT
UPDATE AD_Process_Para SET ColumnName='PartitioningMethod', Name='Partitioning Method', Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.', AD_Element_ID=203882 WHERE UPPER(ColumnName)='PARTITIONINGMETHOD' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:02:04 AM MYT
UPDATE AD_Process_Para SET ColumnName='PartitioningMethod', Name='Partitioning Method', Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.', Placeholder=NULL WHERE AD_Element_ID=203882 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Element SET Description='This is a partition key',Updated=TO_TIMESTAMP('2023-12-13 11:05:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203885
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Column SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203885
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, AD_Element_ID=203885 WHERE UPPER(ColumnName)='ISPARTITIONKEY' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203885 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_InfoColumn SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203885 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Field SET Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203885) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Element SET Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first',Updated=TO_TIMESTAMP('2023-12-13 11:08:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203886
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Column SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Element_ID=203886
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Process_Para SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', AD_Element_ID=203886 WHERE UPPER(ColumnName)='SEQNOPARTITION' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Process_Para SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Element_ID=203886 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_InfoColumn SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Element_ID=203886 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Field SET Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203886) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Element SET Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;',Updated=TO_TIMESTAMP('2023-12-13 11:24:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203883
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Column SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Element_ID=203883
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', AD_Element_ID=203883 WHERE UPPER(ColumnName)='RANGEPARTITIONINTERVAL' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Element_ID=203883 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_InfoColumn SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Element_ID=203883 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Field SET Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203883) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Element SET Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records',Updated=TO_TIMESTAMP('2023-12-13 11:28:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203884
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Column SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Element_ID=203884
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Process_Para SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', AD_Element_ID=203884 WHERE UPPER(ColumnName)='CREATEPARTITION' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Process_Para SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Element_ID=203884 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_InfoColumn SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Element_ID=203884 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Field SET Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203884) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Element SET Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition',Updated=TO_TIMESTAMP('2023-12-13 11:30:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203887
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Column SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Element_ID=203887
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Process_Para SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', AD_Element_ID=203887 WHERE UPPER(ColumnName)='AD_TABLEPARTITION_ID' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Process_Para SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Element_ID=203887 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_InfoColumn SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Element_ID=203887 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Field SET Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203887) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:34:57 AM MYT
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,AD_Reference_Value_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,DisplayLogic,AD_Process_Para_UU,IsEncrypted,IsAutocomplete,IsShowNegateButton) VALUES (200448,0,0,'Y',TO_TIMESTAMP('2023-12-13 11:34:56','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:34:56','YYYY-MM-DD HH24:MI:SS'),100,'Partitioning Method',200157,10,17,200261,'N',2,'N','PartitioningMethod','N','D','@AD_Table_ID@=0 & @Record_ID@=0','c323eb12-5b81-456a-8f23-26a3865bc0f5','N','N','N')
;
-- Dec 13, 2023, 11:35:47 AM MYT
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,DisplayLogic,AD_Process_Para_UU,IsEncrypted,IsAutocomplete,IsShowNegateButton) VALUES (200449,0,0,'Y',TO_TIMESTAMP('2023-12-13 11:35:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:35:46','YYYY-MM-DD HH24:MI:SS'),100,'Table Name',200157,20,10,'N',27,'N',NULL,'TableName','N','D',NULL,'8cc028d6-fd10-4def-8181-bd8acb9e22c4','N','N','N')
;
-- Dec 13, 2023, 11:36:02 AM MYT
UPDATE AD_Process_Para SET DisplayLogic='@AD_Table_ID@=0 & @Record_ID@=0',Updated=TO_TIMESTAMP('2023-12-13 11:36:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200449
;
-- Dec 13, 2023, 11:36:46 AM MYT
UPDATE AD_Process SET Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records',Updated=TO_TIMESTAMP('2023-12-13 11:36:46','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200157
;
-- Dec 13, 2023, 11:46:35 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to rename the original table',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:46:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:46:34','YYYY-MM-DD HH24:MI:SS'),100,200845,'FailedRenameOriginalTable','D','6c2227d1-4fb9-40df-aefe-d11065aebca4')
;
-- Dec 13, 2023, 11:48:37 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Partitioning Method not supported: {0}',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:48:36','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:48:36','YYYY-MM-DD HH24:MI:SS'),100,200846,'PartitioningMethodNotSupported','D','df6db5b6-7fee-4fa0-b759-3a94a22592b2')
;
-- Dec 13, 2023, 11:54:29 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to migrate database constraints',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:54:28','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:54:28','YYYY-MM-DD HH24:MI:SS'),100,200847,'FailedMigrateDatabaseConstraints','D','21993b03-485c-4c0c-a90a-e9f9faf453b4')
;
-- Dec 13, 2023, 11:55:14 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to attach to the default partition',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:55:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:55:13','YYYY-MM-DD HH24:MI:SS'),100,200848,'FailedAttachDefaultPartition','D','e9c6c9ad-9d2f-4d10-9e86-668dce78e10b')
;
-- Dec 13, 2023, 11:58:55 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to create the partitioned table',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:58:54','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:58:54','YYYY-MM-DD HH24:MI:SS'),100,200849,'FailedCreatePartitionedTable','D','aba471b7-75ac-404a-aaba-49af561d32cc')
;
-- Dec 13, 2023, 12:00:12 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to migrate data',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:00:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:00:11','YYYY-MM-DD HH24:MI:SS'),100,200850,'FailedMigrateData','D','9e23b23b-c339-441e-ad0b-0c12e9f494df')
;
-- Dec 13, 2023, 12:01:26 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to run post migration data',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:01:25','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:01:25','YYYY-MM-DD HH24:MI:SS'),100,200851,'FailedRunPostMigrationData','D','393cf32e-97e0-4550-8cd7-ccb79899095c')
;
-- Dec 13, 2023, 12:02:44 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','At least one partition key is required',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:02:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:02:44','YYYY-MM-DD HH24:MI:SS'),100,200852,'PartitionKeyRequired','D','73b18dec-f7f4-460f-8461-795a78e8fa7a')
;
-- Dec 13, 2023, 12:09:23 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Changed in the partitioning method or partition key(s)',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:09:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:09:22','YYYY-MM-DD HH24:MI:SS'),100,200853,'PartitionConfigurationChanged','D','b4ccf587-4631-42ae-a6c5-0e0d005b3f27')
;

View File

@ -0,0 +1,54 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312131420_IDEMPIERE-5943.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Dec 13, 2023, 2:20:14 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Table partition is not empty',0,0,'Y',TO_TIMESTAMP('2023-12-13 14:20:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 14:20:13','YYYY-MM-DD HH24:MI:SS'),100,200854,'TablePartitionNotEmpty','D','fc4d156d-d59f-4449-bfa8-584497efd6b4')
;
-- Dec 13, 2023, 3:44:16 PM MYT
INSERT INTO AD_Menu (AD_Menu_ID,Name,Description,Action,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSummary,AD_Process_ID,IsSOTrx,IsReadOnly,EntityType,IsCentrallyMaintained,AD_Menu_UU) VALUES (200230,'Create/Update Table Partition','Process which create or update table partitions for partitioned tables','P',0,0,'Y',TO_TIMESTAMP('2023-12-13 15:44:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 15:44:14','YYYY-MM-DD HH24:MI:SS'),100,'N',200157,'Y','N','D','N','aeea2c2f-fcd7-422b-a708-a3c2905a47db')
;
-- Dec 13, 2023, 3:44:16 PM MYT
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNodeMM_UU) SELECT t.AD_Client_ID, 0, 'Y', getDate(), 100, getDate(), 100,t.AD_Tree_ID, 200230, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200230)
;
-- Dec 13, 2023, 3:47:37 PM MYT
UPDATE AD_TreeNodeMM SET Parent_ID=153, SeqNo=9,Updated=TO_TIMESTAMP('2023-12-13 15:47:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200230
;
-- Dec 13, 2023, 3:58:59 PM MYT
INSERT INTO AD_Scheduler (AD_Client_ID,Supervisor_ID,IsActive,Processing,AD_Scheduler_ID,AD_Process_ID,CreatedBy,Updated,DateNextRun,AD_Org_ID,UpdatedBy,Created,Name,KeepLogDays,AD_Scheduler_UU,AD_Schedule_ID) VALUES (0,10,'Y','N',200003,200157,100,TO_TIMESTAMP('2023-12-13 15:58:59','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-12-14 15:58:59','YYYY-MM-DD HH24:MI:SS'),0,100,TO_TIMESTAMP('2023-12-13 15:58:59','YYYY-MM-DD HH24:MI:SS'),'Create/Update Table Partitions',7,'46d0a09b-71b5-4ca2-b8ed-a61a3c77999c',200000)
;
-- Dec 13, 2023, 3:59:11 PM MYT
INSERT INTO AD_Scheduler_Para (AD_Process_Para_ID,IsActive,AD_Org_ID,CreatedBy,UpdatedBy,Created,Updated,AD_Client_ID,AD_Scheduler_ID,AD_Scheduler_Para_UU) VALUES (200448,'Y',0,100,100,TO_TIMESTAMP('2023-12-13 15:59:10','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-12-13 15:59:10','YYYY-MM-DD HH24:MI:SS'),0,200003,'b2693a75-9687-4701-967b-27339ed4f260')
;
-- Dec 13, 2023, 3:59:11 PM MYT
INSERT INTO AD_Scheduler_Para (AD_Process_Para_ID,IsActive,AD_Org_ID,CreatedBy,UpdatedBy,Created,Updated,ParameterDefault,AD_Client_ID,AD_Scheduler_ID,AD_Scheduler_Para_UU) VALUES (200449,'Y',0,100,100,TO_TIMESTAMP('2023-12-13 15:59:11','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-12-13 15:59:11','YYYY-MM-DD HH24:MI:SS'),NULL,0,200003,'16a4a485-e81d-46ac-b021-f78e363a75cf')
;
-- Dec 14, 2023, 2:41:34 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid Range Partition Interval','The Range Partition Interval has to match the date/number patterns: ^([1-9]{1}[0-9]?)\s+year(?:s)?\s+([1-9]{1}[0-9]?)\s+month(?:s)?$; ^([1-9]{1}[0-9]?)\s+(year)(?:s)?$; ^([1-9]{1}[0-9]?)\s+(month)(?:s)?$; ^[1-9]\d*$',0,0,'Y',TO_TIMESTAMP('2023-12-14 14:41:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-14 14:41:32','YYYY-MM-DD HH24:MI:SS'),100,200855,'InvalidRangePartitionInterval','D','6d5b187c-246b-427b-9b31-e9d3f4d0d892')
;
-- Dec 14, 2023, 2:53:11 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Range partition key type not supported','Support date and numeric types only',0,0,'Y',TO_TIMESTAMP('2023-12-14 14:53:10','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-14 14:53:10','YYYY-MM-DD HH24:MI:SS'),100,200856,'RangePartitionKeyTypeNotSupported','D','289e23ba-ad2e-4ae8-b777-aa4d08186d15')
;
-- Dec 14, 2023, 3:17:41 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Database adapter doesn''t have table partition support',NULL,0,0,'Y',TO_TIMESTAMP('2023-12-14 15:17:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-14 15:17:40','YYYY-MM-DD HH24:MI:SS'),100,200857,'DBAdapterNoTablePartitionSupport','D','37388fcf-1594-4385-8a10-7aa177ea9d8f')
;
-- Dec 14, 2023, 3:35:29 PM MYT
UPDATE AD_Message SET MsgText='Changed in the table partition configuration',Updated=TO_TIMESTAMP('2023-12-14 15:35:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200853
;
-- Dec 15, 2023, 4:50:28 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Only one partition key is allowed',0,0,'Y',TO_TIMESTAMP('2023-12-15 16:50:27','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-15 16:50:27','YYYY-MM-DD HH24:MI:SS'),100,200858,'OnlyOnePartitionKeyAllowed','D','8e205344-7629-441a-af13-c831bafcbf00')
;

View File

@ -0,0 +1,37 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312160613_IDEMPIERE-5943.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Dec 16, 2023, 6:13:11 AM MYT
UPDATE AD_Field SET SeqNo=560, SeqNoGrid=510,Updated=TO_TIMESTAMP('2023-12-16 06:13:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208093
;
-- Dec 16, 2023, 6:14:08 AM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (208094,'Partitioning Method','Indicates how the Table is partitioned','The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.',101,216283,'Y','@IsPartition@=Y & @IsPartitionKey@=Y',0,550,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-16 06:14:07','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-16 06:14:07','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','46ea66ce-849a-4e6e-a9e5-cd54efee2d78','Y',500,1,2,1,'N','N','N','N')
;
-- Dec 16, 2023, 6:15:38 AM MYT
UPDATE AD_Column SET MandatoryLogic='@IsPartition@=Y & @IsPartitionKey@=Y',Updated=TO_TIMESTAMP('2023-12-16 06:15:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216283
;
-- Dec 17, 2023, 9:50:42 AM MYT
UPDATE AD_Scheduler SET IsActive='N', Record_ID=NULL,Updated=TO_TIMESTAMP('2023-12-17 09:50:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Scheduler_ID=200003
;
-- Dec 18, 2023, 1:51:19 PM MYT
UPDATE AD_Message SET MsgText='Your changes to the current table partition configuration are not supported',Updated=TO_DATE('2023-12-18 13:51:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200853
;
-- Dec 18, 2023, 1:51:40 PM MYT
UPDATE AD_Message SET MsgText='At least one partition key column is required',Updated=TO_DATE('2023-12-18 13:51:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200852
;
-- Dec 18, 2023, 1:52:33 PM MYT
UPDATE AD_Message SET MsgText='Failed to attach default partition',Updated=TO_DATE('2023-12-18 13:52:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200848
;
-- Dec 18, 2023, 1:54:36 PM MYT
UPDATE AD_Message SET MsgText='Only one partition key column is allowed',Updated=TO_DATE('2023-12-18 13:54:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200858
;

View File

@ -0,0 +1,38 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312201102_IDEMPIERE-5943.sql') FROM dual;
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Dec 20, 2023, 11:02:30 AM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,AD_Val_Rule_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml,IsPartitionKey) VALUES (216305,0,'Column','Column in the table','Link to the database column of the table',200411,100,'AD_Column_ID',22,'N','N','Y','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-20 11:02:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-20 11:02:29','YYYY-MM-DD HH24:MI:SS'),100,104,'N','N','D','N','N','N','N','384ead93-7ceb-4a86-80ea-f584db5b78e3','N',0,'N','N','N','N','N')
;
-- Dec 20, 2023, 11:02:35 AM MYT
UPDATE AD_Column SET FKConstraintName='ADColumn_ADTablePartition', FKConstraintType='N',Updated=TO_TIMESTAMP('2023-12-20 11:02:35','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216305
;
-- Dec 20, 2023, 11:02:35 AM MYT
ALTER TABLE AD_TablePartition ADD AD_Column_ID NUMBER(10) NOT NULL
;
-- Dec 20, 2023, 11:02:35 AM MYT
ALTER TABLE AD_TablePartition ADD CONSTRAINT ADColumn_ADTablePartition FOREIGN KEY (AD_Column_ID) REFERENCES ad_column(ad_column_id) DEFERRABLE INITIALLY DEFERRED
;
-- Dec 20, 2023, 11:04:55 AM MYT
UPDATE AD_Field SET SeqNo=70, SeqNoGrid=50,Updated=TO_TIMESTAMP('2023-12-20 11:04:55','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208091
;
-- Dec 20, 2023, 11:05:01 AM MYT
UPDATE AD_Field SET SeqNo=60, SeqNoGrid=40,Updated=TO_TIMESTAMP('2023-12-20 11:05:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208090
;
-- Dec 20, 2023, 11:05:13 AM MYT
UPDATE AD_Field SET SeqNo=50, SeqNoGrid=30,Updated=TO_TIMESTAMP('2023-12-20 11:05:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208087
;
-- Dec 20, 2023, 11:05:55 AM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (208095,'Column','Column in the table','Link to the database column of the table',200381,216305,'Y',0,40,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-20 11:05:55','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-20 11:05:55','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','57c973c1-cf9b-44cb-a150-61c706a1479d','Y',20,4,2,1,'N','N','N','N')
;

View File

@ -0,0 +1,253 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312041549_IDEMPIERE-5943.sql') FROM dual;
-- Dec 4, 2023, 3:49:42 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203881,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:49:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:49:41','YYYY-MM-DD HH24:MI:SS'),100,'IsPartition','Partition','Partition','D','71a4c045-f75b-435e-997f-ca453554d40f')
;
-- Dec 4, 2023, 3:51:05 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216282,0,'Partition',100,'IsPartition','N',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:51:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:51:04','YYYY-MM-DD HH24:MI:SS'),100,203881,'Y','N','D','N','N','N','Y','fae626e9-69df-411a-8d1d-a8e59b3b48df','Y',0,'N','N','N')
;
-- Dec 4, 2023, 3:51:39 PM MYT
UPDATE AD_Column SET IsMandatory='Y',Updated=TO_TIMESTAMP('2023-12-04 15:51:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216282
;
-- Dec 4, 2023, 3:51:47 PM MYT
ALTER TABLE AD_Table ADD COLUMN IsPartition CHAR(1) DEFAULT 'N' CHECK (IsPartition IN ('Y','N')) NOT NULL
;
-- Dec 4, 2023, 3:52:20 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203882,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:52:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:52:19','YYYY-MM-DD HH24:MI:SS'),100,'PartitioningMethod','Partitioning Method','Partitioning Method','D','5dc2d9dd-1e38-4985-a741-2f779891e4df')
;
-- Dec 4, 2023, 3:53:10 PM MYT
INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU,ShowInactive) VALUES (200261,'AD_Column PartitioningMethod','L',0,0,'Y',TO_TIMESTAMP('2023-12-04 15:53:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:53:09','YYYY-MM-DD HH24:MI:SS'),100,'D','N','81b6431b-0afa-49bc-b5fe-be9a7b2481cf','N')
;
-- Dec 4, 2023, 3:53:22 PM MYT
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200684,'Range',200261,'R',0,0,'Y',TO_TIMESTAMP('2023-12-04 15:53:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:53:22','YYYY-MM-DD HH24:MI:SS'),100,'D','d8a5f9ab-574e-4926-93eb-e4a392c36e3c')
;
-- Dec 4, 2023, 3:53:33 PM MYT
INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200685,'List',200261,'L',0,0,'Y',TO_TIMESTAMP('2023-12-04 15:53:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:53:32','YYYY-MM-DD HH24:MI:SS'),100,'D','d909c15e-9b97-4171-87bb-7de77cee4eb8')
;
-- Dec 4, 2023, 3:55:31 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,MandatoryLogic,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216283,0,'Partitioning Method',101,'PartitioningMethod',2,'N','N','N','N','N',0,'N',17,200261,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:55:30','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:55:30','YYYY-MM-DD HH24:MI:SS'),100,203882,'Y','N','D','N','N','@IsPartition@=''Y''','N','Y','b67a043a-019a-479d-81c4-5439a3447aaa','Y',0,'N','N','N')
;
-- Dec 4, 2023, 3:55:42 PM MYT
ALTER TABLE AD_Column ADD COLUMN PartitioningMethod VARCHAR(2) DEFAULT NULL
;
-- Dec 4, 2023, 3:56:10 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203883,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:56:10','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:56:10','YYYY-MM-DD HH24:MI:SS'),100,'RangePartitionInterval','Range Partition Interval','Range Partition Interval','D','f14b1920-8c8f-4cb5-9f85-a579d854625d')
;
-- Dec 4, 2023, 3:59:04 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203884,0,0,'Y',TO_TIMESTAMP('2023-12-04 15:59:04','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 15:59:04','YYYY-MM-DD HH24:MI:SS'),100,'CreatePartition','Create/update partition','Create/update partition','D','356bc70e-12d7-478b-a70f-24adb47024af')
;
-- Dec 4, 2023, 4:02:43 PM MYT
INSERT INTO AD_Process (AD_Process_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,IsReport,Value,IsDirectPrint,Classname,AccessLevel,EntityType,Statistic_Count,Statistic_Seconds,IsBetaFunctionality,ShowHelp,AD_Process_UU,AllowMultipleExecution) VALUES (200157,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:02:42','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:02:42','YYYY-MM-DD HH24:MI:SS'),100,'Create/update partition','N','AD_Table CreatePartition','N','org.idempiere.tablepartition.process.CreatePartition','4','D',0,0,'N','Y','5f9a2aa4-a18d-4629-b613-15d2436c4898','NA')
;
-- Dec 4, 2023, 4:04:16 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,AD_Process_ID,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216285,0,'Create/update partition',100,'CreatePartition',1,'N','N','N','N','N',0,'N',28,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:04:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:04:15','YYYY-MM-DD HH24:MI:SS'),100,203884,'Y',200157,'N','D','N','N','N','Y','65d73bf3-bf25-45dd-aa14-662f511fccb2','Y',0,'Y','N','N')
;
-- Dec 4, 2023, 4:04:33 PM MYT
ALTER TABLE AD_Table ADD COLUMN CreatePartition CHAR(1) DEFAULT NULL
;
-- Dec 4, 2023, 4:05:45 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203885,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:05:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:05:44','YYYY-MM-DD HH24:MI:SS'),100,'IsPartitionKey','Partition Key','Partition Key','D','bac735c9-addb-4dfa-81d7-4506cbad6ed0')
;
-- Dec 4, 2023, 4:06:12 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216286,0,'Partition Key',101,'IsPartitionKey','''N''',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:06:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:06:11','YYYY-MM-DD HH24:MI:SS'),100,203885,'Y','N','D','N','N','N','Y','248d95b0-6318-4821-9053-fa6138d8049b','Y',0,'N','N','N')
;
-- Dec 4, 2023, 4:06:19 PM MYT
ALTER TABLE AD_Column ADD COLUMN IsPartitionKey CHAR(1) DEFAULT 'N' CHECK (IsPartitionKey IN ('Y','N')) NOT NULL
;
-- Dec 4, 2023, 4:08:38 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203886,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:08:38','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:08:38','YYYY-MM-DD HH24:MI:SS'),100,'SeqNoPartition','Partition Key Sequence','Partition Key Sequence','D','d9593a7f-cc70-4403-834e-0dca74044fdb')
;
-- Dec 4, 2023, 4:21:40 PM MYT
INSERT INTO AD_Table (AD_Table_ID,Name,TableName,LoadSeq,AccessLevel,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSecurityEnabled,IsDeleteable,IsHighVolume,IsView,EntityType,ImportTable,IsChangeLog,ReplicationType,CopyColumnsFromTable,IsCentrallyMaintained,AD_Table_UU,Processing,DatabaseViewDrop,CopyComponentsFromView,CreateWindowFromTable,IsShowInDrillOptions) VALUES (200411,'Table Partition','AD_TablePartition',0,'4',0,0,'Y',TO_TIMESTAMP('2023-12-04 16:21:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:21:40','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','N','D','N','Y','L','N','Y','b778984a-9a96-4db4-a54f-8f47e6583f5e','N','N','N','N','N')
;
-- Dec 4, 2023, 4:21:41 PM MYT
INSERT INTO AD_Sequence (Name,CurrentNext,IsAudited,StartNewYear,Description,IsActive,IsTableID,AD_Client_ID,AD_Org_ID,Created,CreatedBy,Updated,UpdatedBy,AD_Sequence_ID,IsAutoSequence,StartNo,IncrementNo,CurrentNextSys,AD_Sequence_UU) VALUES ('AD_TablePartition',1000000,'N','N','Table AD_TablePartition','Y','Y',0,0,TO_TIMESTAMP('2023-12-04 16:21:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:21:41','YYYY-MM-DD HH24:MI:SS'),100,200482,'Y',1000000,1,200000,'25e2994d-bed5-4a71-a6da-7b1b96c6cb77')
;
-- Dec 4, 2023, 4:25:41 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,AD_Val_Rule_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216287,0,'Tenant','Tenant for this installation.','A Tenant is a company or a legal entity. You cannot share data between Tenants.',200411,129,'AD_Client_ID','@#AD_Client_ID@',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:39','YYYY-MM-DD HH24:MI:SS'),100,102,'N','N','D','N','N','N','Y','8aa0a7f1-d581-4075-b7dd-229c81528e5f','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:25:42 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203887,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:42','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:42','YYYY-MM-DD HH24:MI:SS'),100,'AD_TablePartition_ID','Table Partition','Table Partition','D','1751f83e-723a-49a4-894d-eee7526a2878')
;
-- Dec 4, 2023, 4:25:43 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216289,0,'Table Partition',200411,'AD_TablePartition_ID',22,'Y','N','N','N','N',0,'N',13,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:41','YYYY-MM-DD HH24:MI:SS'),100,203887,'N','N','D','N','N','N','Y','2dca6112-15b8-4bdc-836d-29067967f910','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:45 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203888,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,'AD_TablePartition_UU','AD_TablePartition_UU','AD_TablePartition_UU','D','771b52d3-12ba-4c1f-b2ec-e1bfc4465173')
;
-- Dec 4, 2023, 4:25:45 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216291,0,'AD_TablePartition_UU',200411,'AD_TablePartition_UU',36,'N','N','N','N','N',0,'N',200231,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:44','YYYY-MM-DD HH24:MI:SS'),100,203888,'N','N','D','N','N','N','Y','b28719af-aa1e-4461-8519-135684688bc0','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:46 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,AD_Val_Rule_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216292,0,'Organization','Organizational entity within tenant','An organization is a unit of your tenant or legal entity - examples are store, department. You can share data between organizations.',200411,104,'AD_Org_ID','@#AD_Org_ID@',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:45','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:45','YYYY-MM-DD HH24:MI:SS'),100,113,'N','N','D','N','N','N','Y','cbeed504-0d75-453b-8b85-07e7db4586ee','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:25:47 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216293,0,'Created','Date this record was created','The Created field indicates the date that this record was created.',200411,'Created','SYSDATE',7,'N','N','N','N','N',0,'N',16,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:46','YYYY-MM-DD HH24:MI:SS'),100,245,'N','N','D','N','N','N','Y','89ef8f7b-0f27-4314-a9c2-163d90e630fb','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:48 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216294,0,'Created By','User who created this records','The Created By field indicates the user who created this record.',200411,'CreatedBy',22,'N','N','N','N','N',0,'N',30,110,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:47','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:47','YYYY-MM-DD HH24:MI:SS'),100,246,'N','N','D','N','N','N','Y','2f778d0a-ba9d-437b-ad54-74e43bd80b4a','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:25:49 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216296,0,'Active','The record is active in the system','There are two methods of making records unavailable in the system: One is to delete the record, the other is to de-activate the record. A de-activated record is not available for selection, but available for reports.
There are two reasons for de-activating and not deleting records:
(1) The system requires the record for audit purposes.
(2) The record is referenced by other records. E.g., you cannot delete a Business Partner, if there are invoices for this partner record existing. You de-activate the Business Partner and prevent that this record is used for future entries.',200411,'IsActive','Y',1,'N','N','N','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,348,'Y','N','D','N','N','N','Y','fc84d078-1b2c-4e8b-824d-bc22e45f0a7e','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:50 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216297,0,'Name','Alphanumeric identifier of the entity','The name of an entity (record) is used as an default search option in addition to the search key. The name is up to 60 characters in length.',200411,'Name',60,'N','N','Y','N','Y',0,'N',10,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:49','YYYY-MM-DD HH24:MI:SS'),100,469,'Y','Y','D','N','N','N','Y','9682330b-98e7-4668-84f5-92e44e16b4cd','Y',20,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:51 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216298,0,'Updated','Date this record was updated','The Updated field indicates the date that this record was updated.',200411,'Updated','SYSDATE',7,'N','N','N','N','N',0,'N',16,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:50','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:50','YYYY-MM-DD HH24:MI:SS'),100,607,'N','N','D','N','N','N','Y','e8c449c5-674a-4482-baef-74dc7af4ae70','N',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:25:52 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216299,0,'Updated By','User who updated this records','The Updated By field indicates the user who updated this record.',200411,'UpdatedBy',22,'N','N','N','N','N',0,'N',30,110,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:25:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:25:51','YYYY-MM-DD HH24:MI:SS'),100,608,'N','N','D','N','N','N','Y','683a0936-b0f2-4283-9191-481832116399','N',0,'N','N','D','N')
;
-- Dec 4, 2023, 4:30:01 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (216300,0,'Table','Database Table information','The Database Table provides the information of the table definition',200411,'AD_Table_ID',10,'N','Y','Y','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:30:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:30:00','YYYY-MM-DD HH24:MI:SS'),100,126,'N','N','D','N','N','N','Y','a8c6c6c3-c965-4b34-a274-c3b7ec6d3240','Y',0,'N','N','N','N')
;
-- Dec 4, 2023, 4:31:20 PM MYT
INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,PrintName,EntityType,AD_Element_UU) VALUES (203889,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:31:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:31:19','YYYY-MM-DD HH24:MI:SS'),100,'ExpressionPartition','Expression','SQL clause for partition','Expression','D','46974aa7-440e-4473-8092-cf80e3b98c2c')
;
-- Dec 4, 2023, 4:34:29 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216301,0,'Expression','SQL clause for partition',200411,'ExpressionPartition',250,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_TIMESTAMP('2023-12-04 16:34:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:34:29','YYYY-MM-DD HH24:MI:SS'),100,203889,'Y','N','D','N','N','N','Y','d90007d9-3737-4d8a-8acb-6beeec3fce2c','Y',0,'N','N','N')
;
-- Dec 4, 2023, 4:37:38 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208078,'IsPartition',100,216282,'Y',1,250,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 16:37:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:37:37','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','d0e6d1e0-96a6-4f3d-8747-061b28c0ef47','Y',210,2,2)
;
-- Dec 4, 2023, 4:37:40 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208081,'Create/update partition',100,216285,'Y',1,280,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 16:37:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 16:37:39','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','0ca9fea4-c0bf-4a97-b8a9-501667ce767c','Y',240,2,2)
;
-- Dec 4, 2023, 5:58:50 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y',Updated=TO_TIMESTAMP('2023-12-04 17:58:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208079
;
-- Dec 4, 2023, 6:02:19 PM MYT
UPDATE AD_Column SET IsToolbarButton='N',Updated=TO_TIMESTAMP('2023-12-04 18:02:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216285
;
-- Dec 4, 2023, 6:03:28 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y',Updated=TO_TIMESTAMP('2023-12-04 18:03:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208081
;
-- Dec 4, 2023, 6:06:42 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208082,'Partition Key',101,216286,'Y',1,530,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:06:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:06:41','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','f37e6afb-66b4-4fc4-96b6-411675c109a8','Y',480,2,2)
;
-- Dec 4, 2023, 6:08:21 PM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (216302,0,'Partition Key Sequence',101,'SeqNoPartition',14,'N','N','N','N','N',0,'N',11,0,0,'Y',TO_TIMESTAMP('2023-12-04 18:08:20','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:08:20','YYYY-MM-DD HH24:MI:SS'),100,203886,'Y','N','D','N','N','N','Y','6fe55ecb-5be5-43bc-a347-15ba40b1e88e','Y',0,'N','N','N')
;
-- Dec 4, 2023, 6:08:28 PM MYT
ALTER TABLE AD_Column ADD COLUMN SeqNoPartition NUMERIC(10) DEFAULT NULL
;
-- Dec 4, 2023, 6:09:25 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208083,'Partition Key Sequence',101,216302,'Y',14,540,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:09:24','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:09:24','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','7f43d839-4d4c-46df-9bd4-5a564265a7f9','Y',490,2)
;
-- Dec 4, 2023, 6:10:12 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y',Updated=TO_TIMESTAMP('2023-12-04 18:10:12','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208082
;
-- Dec 4, 2023, 6:10:38 PM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y & @IsPartitionKey@=Y',Updated=TO_TIMESTAMP('2023-12-04 18:10:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208083
;
-- Dec 4, 2023, 6:31:40 PM MYT
UPDATE AD_Field SET XPosition=4,Updated=TO_TIMESTAMP('2023-12-04 18:31:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208083
;
-- Dec 4, 2023, 6:35:00 PM MYT
INSERT INTO AD_Tab (AD_Tab_ID,Name,AD_Window_ID,SeqNo,IsSingleRow,AD_Table_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,HasTree,IsInfoTab,IsTranslationTab,IsReadOnly,Processing,ImportFields,TabLevel,IsSortTab,EntityType,DisplayLogic,IsInsertRecord,IsAdvancedTab,AD_Tab_UU,TreeDisplayedOn,IsLookupOnlySelection,IsAllowAdvancedLookup,MaxQueryRecords) VALUES (200381,'Table Partition',100,120,'Y',200411,0,0,'Y',TO_TIMESTAMP('2023-12-04 18:34:59','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:34:59','YYYY-MM-DD HH24:MI:SS'),100,'N','N','N','Y','N','N',1,'N','D','@IsPartition@=''Y''','N','N','6eecaed6-a84a-4d43-adbc-954917c76d2a','B','N','Y',0)
;
-- Dec 4, 2023, 6:35:11 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (208084,'Tenant','Tenant for this installation.','A Tenant is a company or a legal entity. You cannot share data between Tenants.',200381,216287,'Y',22,10,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','40f081a2-c503-467c-926b-d963f7c01312','N',2)
;
-- Dec 4, 2023, 6:35:12 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsAllowCopy,IsDisplayedGrid,XPosition,ColumnSpan) VALUES (208085,'Organization','Organizational entity within tenant','An organization is a unit of your tenant or legal entity - examples are store, department. You can share data between organizations.',200381,216292,'Y',22,20,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:11','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','737d9a62-d5f2-412d-9a9a-420d2f32c06d','Y','N',4,2)
;
-- Dec 4, 2023, 6:35:13 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208086,'Table','Database Table information','The Database Table provides the information of the table definition',200381,216300,'Y',10,30,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:12','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:12','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','d2c0143c-2da2-43c5-8950-54c066f562a4','Y',10,2)
;
-- Dec 4, 2023, 6:35:14 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208087,'Name','Alphanumeric identifier of the entity','The name of an entity (record) is used as an default search option in addition to the search key. The name is up to 60 characters in length.',200381,216297,'Y',60,40,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:13','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','b0cbc492-2be7-49f3-ad7f-c553037c8d0d','Y',20,5)
;
-- Dec 4, 2023, 6:35:14 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (208088,'Table Partition',200381,216289,'N',22,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:14','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','4f8e1c9e-205a-43d6-884b-e8503eef6d86','N',2)
;
-- Dec 4, 2023, 6:35:16 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,ColumnSpan) VALUES (208089,'AD_TablePartition_UU',200381,216291,'N',36,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:15','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','12666f96-7ead-472f-a9a0-b78ba5b5b30a','N',2)
;
-- Dec 4, 2023, 6:35:16 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208090,'Expression','SQL clause for partition',200381,216301,'Y',250,50,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','85314375-dd91-411e-b8fe-89649a84e039','Y',30,5)
;
-- Dec 4, 2023, 6:35:17 PM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan) VALUES (208091,'Active','The record is active in the system','There are two methods of making records unavailable in the system: One is to delete the record, the other is to de-activate the record. A de-activated record is not available for selection, but available for reports.
There are two reasons for de-activating and not deleting records:
(1) The system requires the record for audit purposes.
(2) The record is referenced by other records. E.g., you cannot delete a Business Partner, if there are invoices for this partner record existing. You de-activate the Business Partner and prevent that this record is used for future entries.',200381,216296,'Y',1,60,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-04 18:35:16','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','aa8e85d5-3cc6-4cc7-ab6a-0c36b5f1a8ec','Y',40,2,2)
;
-- Dec 4, 2023, 6:37:58 PM MYT
UPDATE AD_Column SET IsMandatory='Y',Updated=TO_TIMESTAMP('2023-12-04 18:37:58','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216301
;
-- Dec 4, 2023, 6:38:11 PM MYT
UPDATE AD_Column SET IsUpdateable='N', FKConstraintName='ADTable_ADTablePartition', FKConstraintType='N',Updated=TO_TIMESTAMP('2023-12-04 18:38:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216300
;
-- Dec 4, 2023, 6:38:12 PM MYT
CREATE TABLE AD_TablePartition (AD_Client_ID NUMERIC(10) DEFAULT NULL , AD_Org_ID NUMERIC(10) DEFAULT NULL , AD_Table_ID NUMERIC(10) NOT NULL, AD_TablePartition_ID NUMERIC(10) DEFAULT NULL , AD_TablePartition_UU VARCHAR(36) DEFAULT NULL , Created TIMESTAMP DEFAULT statement_timestamp(), CreatedBy NUMERIC(10) DEFAULT NULL , ExpressionPartition VARCHAR(250) NOT NULL, IsActive CHAR(1) DEFAULT 'Y' CHECK (IsActive IN ('Y','N')), Name VARCHAR(60) NOT NULL, Updated TIMESTAMP DEFAULT statement_timestamp(), UpdatedBy NUMERIC(10) DEFAULT NULL , CONSTRAINT AD_TablePartition_Key PRIMARY KEY (AD_TablePartition_ID), CONSTRAINT AD_TablePartition_UU_idx UNIQUE (AD_TablePartition_UU))
;
-- Dec 4, 2023, 6:38:12 PM MYT
ALTER TABLE AD_TablePartition ADD CONSTRAINT ADTable_ADTablePartition FOREIGN KEY (AD_Table_ID) REFERENCES ad_table(ad_table_id) DEFERRABLE INITIALLY DEFERRED
;

View File

@ -0,0 +1,234 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312131039_IDEMPIERE-5943.sql') FROM dual;
-- Dec 13, 2023, 10:39:08 AM MYT
UPDATE AD_Column SET DefaultValue='@SQL=SELECT COALESCE(MAX(SeqNoPartition),0)+10 AS DefaultValue FROM AD_Column WHERE AD_Table_ID=@AD_Table_ID@ AND IsActive=''Y'' AND IsPartitionKey=''Y''' ,Updated=TO_TIMESTAMP('2023-12-13 10:39:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216302
;
-- Dec 13, 2023, 10:41:20 AM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,MandatoryLogic,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml,IsPartitionKey,SeqNoPartition) VALUES (216304,0,'Range Partition Interval',101,'RangePartitionInterval',30,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_TIMESTAMP('2023-12-13 10:41:19','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 10:41:19','YYYY-MM-DD HH24:MI:SS'),100,203883,'Y','N','D','N','N','@IsPartition@=''Y'' & @PartitioningMethod@=''R''','N','Y','e8dff995-1857-4653-8aa2-18d6e89620fd','Y',0,'N','N','N','N','N',0)
;
-- Dec 13, 2023, 10:41:31 AM MYT
ALTER TABLE AD_Column ADD COLUMN RangePartitionInterval VARCHAR(30) DEFAULT NULL
;
-- Dec 13, 2023, 10:42:52 AM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (208093,'Range Partition Interval',101,216304,'Y',30,550,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-13 10:42:51','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 10:42:51','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','e4d0ddb5-cc5b-4969-96fd-718a759635ff','Y',500,2)
;
-- Dec 13, 2023, 10:44:43 AM MYT
UPDATE AD_Field SET DisplayLogic='@IsPartition@=Y & @IsPartitionKey@=Y & @PartitioningMethod@=R',Updated=TO_TIMESTAMP('2023-12-13 10:44:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208093
;
-- Dec 13, 2023, 10:54:43 AM MYT
UPDATE AD_Element SET Description='This is a partitioned table',Updated=TO_TIMESTAMP('2023-12-13 10:54:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203881
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Column SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203881
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, AD_Element_ID=203881 WHERE UPPER(ColumnName)='ISPARTITION' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203881 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_InfoColumn SET ColumnName='IsPartition', Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203881 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 10:54:44 AM MYT
UPDATE AD_Field SET Name='Partition', Description='This is a partitioned table', Help=NULL, Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203881) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:02:03 AM MYT
UPDATE AD_Element SET Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.',Updated=TO_TIMESTAMP('2023-12-13 11:02:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203882
;
-- Dec 13, 2023, 11:02:03 AM MYT
UPDATE AD_Column SET ColumnName='PartitioningMethod', Name='Partitioning Method', Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.', Placeholder=NULL WHERE AD_Element_ID=203882
;
-- Dec 13, 2023, 11:02:04 AM MYT
UPDATE AD_Process_Para SET ColumnName='PartitioningMethod', Name='Partitioning Method', Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.', AD_Element_ID=203882 WHERE UPPER(ColumnName)='PARTITIONINGMETHOD' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:02:04 AM MYT
UPDATE AD_Process_Para SET ColumnName='PartitioningMethod', Name='Partitioning Method', Description='Indicates how the Table is partitioned', Help='The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.', Placeholder=NULL WHERE AD_Element_ID=203882 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Element SET Description='This is a partition key',Updated=TO_TIMESTAMP('2023-12-13 11:05:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203885
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Column SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203885
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, AD_Element_ID=203885 WHERE UPPER(ColumnName)='ISPARTITIONKEY' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203885 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_InfoColumn SET ColumnName='IsPartitionKey', Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Element_ID=203885 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:05:16 AM MYT
UPDATE AD_Field SET Name='Partition Key', Description='This is a partition key', Help=NULL, Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203885) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Element SET Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first',Updated=TO_TIMESTAMP('2023-12-13 11:08:03','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203886
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Column SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Element_ID=203886
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Process_Para SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', AD_Element_ID=203886 WHERE UPPER(ColumnName)='SEQNOPARTITION' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Process_Para SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Element_ID=203886 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_InfoColumn SET ColumnName='SeqNoPartition', Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Element_ID=203886 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:08:03 AM MYT
UPDATE AD_Field SET Name='Partition Key Sequence', Description='Indicates the order of partition keys', Help='The Partition Key Sequence indicates the order of the partition keys where the lowest number comes first', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203886) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Element SET Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;',Updated=TO_TIMESTAMP('2023-12-13 11:24:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203883
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Column SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Element_ID=203883
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', AD_Element_ID=203883 WHERE UPPER(ColumnName)='RANGEPARTITIONINTERVAL' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Process_Para SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Element_ID=203883 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_InfoColumn SET ColumnName='RangePartitionInterval', Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Element_ID=203883 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:24:16 AM MYT
UPDATE AD_Field SET Name='Range Partition Interval', Description='Indicates the interval used in a range partitioning', Help='The Range Partition Interval indicates the interval used in a range partitioning (date or number). Examples of date intervals: 1 year; 6 months; Examples of number intervals: 5000; 100000;', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203883) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Element SET Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records',Updated=TO_TIMESTAMP('2023-12-13 11:28:17','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203884
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Column SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Element_ID=203884
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Process_Para SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', AD_Element_ID=203884 WHERE UPPER(ColumnName)='CREATEPARTITION' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Process_Para SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Element_ID=203884 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_InfoColumn SET ColumnName='CreatePartition', Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Element_ID=203884 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:28:17 AM MYT
UPDATE AD_Field SET Name='Create/update partition', Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203884) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Element SET Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition',Updated=TO_TIMESTAMP('2023-12-13 11:30:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Element_ID=203887
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Column SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Element_ID=203887
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Process_Para SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', AD_Element_ID=203887 WHERE UPPER(ColumnName)='AD_TABLEPARTITION_ID' AND IsCentrallyMaintained='Y' AND AD_Element_ID IS NULL
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Process_Para SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Element_ID=203887 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_InfoColumn SET ColumnName='AD_TablePartition_ID', Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Element_ID=203887 AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:30:42 AM MYT
UPDATE AD_Field SET Name='Table Partition', Description='Database Table Partition information', Help='The Database Table Partition provides the information of the table partition definition', Placeholder=NULL WHERE AD_Column_ID IN (SELECT AD_Column_ID FROM AD_Column WHERE AD_Element_ID=203887) AND IsCentrallyMaintained='Y'
;
-- Dec 13, 2023, 11:34:57 AM MYT
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,AD_Reference_Value_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,DisplayLogic,AD_Process_Para_UU,IsEncrypted,IsAutocomplete,IsShowNegateButton) VALUES (200448,0,0,'Y',TO_TIMESTAMP('2023-12-13 11:34:56','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:34:56','YYYY-MM-DD HH24:MI:SS'),100,'Partitioning Method',200157,10,17,200261,'N',2,'N','PartitioningMethod','N','D','@AD_Table_ID@=0 & @Record_ID@=0','c323eb12-5b81-456a-8f23-26a3865bc0f5','N','N','N')
;
-- Dec 13, 2023, 11:35:47 AM MYT
INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,DisplayLogic,AD_Process_Para_UU,IsEncrypted,IsAutocomplete,IsShowNegateButton) VALUES (200449,0,0,'Y',TO_TIMESTAMP('2023-12-13 11:35:46','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:35:46','YYYY-MM-DD HH24:MI:SS'),100,'Table Name',200157,20,10,'N',27,'N',NULL,'TableName','N','D',NULL,'8cc028d6-fd10-4def-8181-bd8acb9e22c4','N','N','N')
;
-- Dec 13, 2023, 11:36:02 AM MYT
UPDATE AD_Process_Para SET DisplayLogic='@AD_Table_ID@=0 & @Record_ID@=0',Updated=TO_TIMESTAMP('2023-12-13 11:36:02','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200449
;
-- Dec 13, 2023, 11:36:46 AM MYT
UPDATE AD_Process SET Description='Process which create or update table partitions based on the table and column records', Help='The Create/update partition process will create or update table partitions based on the information in the table and column records',Updated=TO_TIMESTAMP('2023-12-13 11:36:46','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200157
;
-- Dec 13, 2023, 11:46:35 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to rename the original table',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:46:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:46:34','YYYY-MM-DD HH24:MI:SS'),100,200845,'FailedRenameOriginalTable','D','6c2227d1-4fb9-40df-aefe-d11065aebca4')
;
-- Dec 13, 2023, 11:48:37 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Partitioning Method not supported: {0}',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:48:36','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:48:36','YYYY-MM-DD HH24:MI:SS'),100,200846,'PartitioningMethodNotSupported','D','df6db5b6-7fee-4fa0-b759-3a94a22592b2')
;
-- Dec 13, 2023, 11:54:29 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to migrate database constraints',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:54:28','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:54:28','YYYY-MM-DD HH24:MI:SS'),100,200847,'FailedMigrateDatabaseConstraints','D','21993b03-485c-4c0c-a90a-e9f9faf453b4')
;
-- Dec 13, 2023, 11:55:14 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to attach to the default partition',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:55:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:55:13','YYYY-MM-DD HH24:MI:SS'),100,200848,'FailedAttachDefaultPartition','D','e9c6c9ad-9d2f-4d10-9e86-668dce78e10b')
;
-- Dec 13, 2023, 11:58:55 AM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to create the partitioned table',0,0,'Y',TO_TIMESTAMP('2023-12-13 11:58:54','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 11:58:54','YYYY-MM-DD HH24:MI:SS'),100,200849,'FailedCreatePartitionedTable','D','aba471b7-75ac-404a-aaba-49af561d32cc')
;
-- Dec 13, 2023, 12:00:12 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to migrate data',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:00:11','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:00:11','YYYY-MM-DD HH24:MI:SS'),100,200850,'FailedMigrateData','D','9e23b23b-c339-441e-ad0b-0c12e9f494df')
;
-- Dec 13, 2023, 12:01:26 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to run post migration data',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:01:25','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:01:25','YYYY-MM-DD HH24:MI:SS'),100,200851,'FailedRunPostMigrationData','D','393cf32e-97e0-4550-8cd7-ccb79899095c')
;
-- Dec 13, 2023, 12:02:44 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','At least one partition key is required',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:02:44','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:02:44','YYYY-MM-DD HH24:MI:SS'),100,200852,'PartitionKeyRequired','D','73b18dec-f7f4-460f-8461-795a78e8fa7a')
;
-- Dec 13, 2023, 12:09:23 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Changed in the partitioning method or partition key(s)',0,0,'Y',TO_TIMESTAMP('2023-12-13 12:09:22','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 12:09:22','YYYY-MM-DD HH24:MI:SS'),100,200853,'PartitionConfigurationChanged','D','b4ccf587-4631-42ae-a6c5-0e0d005b3f27')
;

View File

@ -0,0 +1,51 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312131420_IDEMPIERE-5943.sql') FROM dual;
-- Dec 13, 2023, 2:20:14 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Table partition is not empty',0,0,'Y',TO_TIMESTAMP('2023-12-13 14:20:13','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 14:20:13','YYYY-MM-DD HH24:MI:SS'),100,200854,'TablePartitionNotEmpty','D','fc4d156d-d59f-4449-bfa8-584497efd6b4')
;
-- Dec 13, 2023, 3:44:16 PM MYT
INSERT INTO AD_Menu (AD_Menu_ID,Name,Description,"action",AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsSummary,AD_Process_ID,IsSOTrx,IsReadOnly,EntityType,IsCentrallyMaintained,AD_Menu_UU) VALUES (200230,'Create/Update Table Partition','Process which create or update table partitions for partitioned tables','P',0,0,'Y',TO_TIMESTAMP('2023-12-13 15:44:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-13 15:44:14','YYYY-MM-DD HH24:MI:SS'),100,'N',200157,'Y','N','D','N','aeea2c2f-fcd7-422b-a708-a3c2905a47db')
;
-- Dec 13, 2023, 3:44:16 PM MYT
INSERT INTO AD_TreeNodeMM (AD_Client_ID,AD_Org_ID, IsActive,Created,CreatedBy,Updated,UpdatedBy, AD_Tree_ID, Node_ID, Parent_ID, SeqNo, AD_TreeNodeMM_UU) SELECT t.AD_Client_ID, 0, 'Y', statement_timestamp(), 100, statement_timestamp(), 100,t.AD_Tree_ID, 200230, 0, 999, Generate_UUID() FROM AD_Tree t WHERE t.AD_Client_ID=0 AND t.IsActive='Y' AND t.IsAllNodes='Y' AND t.TreeType='MM' AND NOT EXISTS (SELECT * FROM AD_TreeNodeMM e WHERE e.AD_Tree_ID=t.AD_Tree_ID AND Node_ID=200230)
;
-- Dec 13, 2023, 3:47:37 PM MYT
UPDATE AD_TreeNodeMM SET Parent_ID=153, SeqNo=9,Updated=TO_TIMESTAMP('2023-12-13 15:47:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tree_ID=10 AND Node_ID=200230
;
-- Dec 13, 2023, 3:58:59 PM MYT
INSERT INTO AD_Scheduler (AD_Client_ID,Supervisor_ID,IsActive,Processing,AD_Scheduler_ID,AD_Process_ID,CreatedBy,Updated,DateNextRun,AD_Org_ID,UpdatedBy,Created,Name,KeepLogDays,AD_Scheduler_UU,AD_Schedule_ID) VALUES (0,10,'Y','N',200003,200157,100,TO_TIMESTAMP('2023-12-13 15:58:59','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-12-14 15:58:59','YYYY-MM-DD HH24:MI:SS'),0,100,TO_TIMESTAMP('2023-12-13 15:58:59','YYYY-MM-DD HH24:MI:SS'),'Create/Update Table Partitions',7,'46d0a09b-71b5-4ca2-b8ed-a61a3c77999c',200000)
;
-- Dec 13, 2023, 3:59:11 PM MYT
INSERT INTO AD_Scheduler_Para (AD_Process_Para_ID,IsActive,AD_Org_ID,CreatedBy,UpdatedBy,Created,Updated,AD_Client_ID,AD_Scheduler_ID,AD_Scheduler_Para_UU) VALUES (200448,'Y',0,100,100,TO_TIMESTAMP('2023-12-13 15:59:10','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-12-13 15:59:10','YYYY-MM-DD HH24:MI:SS'),0,200003,'b2693a75-9687-4701-967b-27339ed4f260')
;
-- Dec 13, 2023, 3:59:11 PM MYT
INSERT INTO AD_Scheduler_Para (AD_Process_Para_ID,IsActive,AD_Org_ID,CreatedBy,UpdatedBy,Created,Updated,ParameterDefault,AD_Client_ID,AD_Scheduler_ID,AD_Scheduler_Para_UU) VALUES (200449,'Y',0,100,100,TO_TIMESTAMP('2023-12-13 15:59:11','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2023-12-13 15:59:11','YYYY-MM-DD HH24:MI:SS'),NULL,0,200003,'16a4a485-e81d-46ac-b021-f78e363a75cf')
;
-- Dec 14, 2023, 2:41:34 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Invalid Range Partition Interval',E'The Range Partition Interval has to match the date/number patterns: ^([1-9]{1}[0-9]?)\\s+year(?:s)?\\s+([1-9]{1}[0-9]?)\\s+month(?:s)?$; ^([1-9]{1}[0-9]?)\\s+(year)(?:s)?$; ^([1-9]{1}[0-9]?)\\s+(month)(?:s)?$; ^[1-9]\\d*$',0,0,'Y',TO_TIMESTAMP('2023-12-14 14:41:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-14 14:41:32','YYYY-MM-DD HH24:MI:SS'),100,200855,'InvalidRangePartitionInterval','D','6d5b187c-246b-427b-9b31-e9d3f4d0d892')
;
-- Dec 14, 2023, 2:53:11 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Range partition key type not supported','Support date and numeric types only',0,0,'Y',TO_TIMESTAMP('2023-12-14 14:53:10','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-14 14:53:10','YYYY-MM-DD HH24:MI:SS'),100,200856,'RangePartitionKeyTypeNotSupported','D','289e23ba-ad2e-4ae8-b777-aa4d08186d15')
;
-- Dec 14, 2023, 3:17:41 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,MsgTip,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Database adapter doesn''t have table partition support',NULL,0,0,'Y',TO_TIMESTAMP('2023-12-14 15:17:40','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-14 15:17:40','YYYY-MM-DD HH24:MI:SS'),100,200857,'DBAdapterNoTablePartitionSupport','D','37388fcf-1594-4385-8a10-7aa177ea9d8f')
;
-- Dec 14, 2023, 3:35:29 PM MYT
UPDATE AD_Message SET MsgText='Changed in the table partition configuration',Updated=TO_TIMESTAMP('2023-12-14 15:35:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200853
;
-- Dec 15, 2023, 4:50:28 PM MYT
INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Only one partition key is allowed',0,0,'Y',TO_TIMESTAMP('2023-12-15 16:50:27','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-15 16:50:27','YYYY-MM-DD HH24:MI:SS'),100,200858,'OnlyOnePartitionKeyAllowed','D','8e205344-7629-441a-af13-c831bafcbf00')
;

View File

@ -0,0 +1,34 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312160613_IDEMPIERE-5943.sql') FROM dual;
-- Dec 16, 2023, 6:13:11 AM MYT
UPDATE AD_Field SET SeqNo=560, SeqNoGrid=510,Updated=TO_TIMESTAMP('2023-12-16 06:13:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208093
;
-- Dec 16, 2023, 6:14:08 AM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (208094,'Partitioning Method','Indicates how the Table is partitioned','The Partitioning Method indicates how the Table is partitioned (List or Range). List partitioning - The data distribution is defined by a discrete list of values. Range Partitioning - The data is distributed based on a range of values.',101,216283,'Y','@IsPartition@=Y & @IsPartitionKey@=Y',0,550,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-16 06:14:07','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-16 06:14:07','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','46ea66ce-849a-4e6e-a9e5-cd54efee2d78','Y',500,1,2,1,'N','N','N','N')
;
-- Dec 16, 2023, 6:15:38 AM MYT
UPDATE AD_Column SET MandatoryLogic='@IsPartition@=Y & @IsPartitionKey@=Y',Updated=TO_TIMESTAMP('2023-12-16 06:15:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216283
;
-- Dec 17, 2023, 9:50:42 AM MYT
UPDATE AD_Scheduler SET IsActive='N', Record_ID=NULL,Updated=TO_TIMESTAMP('2023-12-17 09:50:42','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Scheduler_ID=200003
;
-- Dec 18, 2023, 1:51:19 PM MYT
UPDATE AD_Message SET MsgText='Your changes to the current table partition configuration are not supported',Updated=TO_TIMESTAMP('2023-12-18 13:51:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200853
;
-- Dec 18, 2023, 1:51:40 PM MYT
UPDATE AD_Message SET MsgText='At least one partition key column is required',Updated=TO_TIMESTAMP('2023-12-18 13:51:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200852
;
-- Dec 18, 2023, 1:52:33 PM MYT
UPDATE AD_Message SET MsgText='Failed to attach default partition',Updated=TO_TIMESTAMP('2023-12-18 13:52:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200848
;
-- Dec 18, 2023, 1:54:36 PM MYT
UPDATE AD_Message SET MsgText='Only one partition key column is allowed',Updated=TO_TIMESTAMP('2023-12-18 13:54:36','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Message_ID=200858
;

View File

@ -0,0 +1,35 @@
-- IDEMPIERE-5943 Implement table partitioning support
SELECT register_migration_script('202312201102_IDEMPIERE-5943.sql') FROM dual;
-- Dec 20, 2023, 11:02:30 AM MYT
INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,AD_Val_Rule_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml,IsPartitionKey) VALUES (216305,0,'Column','Column in the table','Link to the database column of the table',200411,100,'AD_Column_ID',22,'N','N','Y','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2023-12-20 11:02:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-20 11:02:29','YYYY-MM-DD HH24:MI:SS'),100,104,'N','N','D','N','N','N','N','384ead93-7ceb-4a86-80ea-f584db5b78e3','N',0,'N','N','N','N','N')
;
-- Dec 20, 2023, 11:02:35 AM MYT
UPDATE AD_Column SET FKConstraintName='ADColumn_ADTablePartition', FKConstraintType='N',Updated=TO_TIMESTAMP('2023-12-20 11:02:35','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=216305
;
-- Dec 20, 2023, 11:02:35 AM MYT
ALTER TABLE AD_TablePartition ADD COLUMN AD_Column_ID NUMERIC(10) NOT NULL
;
-- Dec 20, 2023, 11:02:35 AM MYT
ALTER TABLE AD_TablePartition ADD CONSTRAINT ADColumn_ADTablePartition FOREIGN KEY (AD_Column_ID) REFERENCES ad_column(ad_column_id) DEFERRABLE INITIALLY DEFERRED
;
-- Dec 20, 2023, 11:04:55 AM MYT
UPDATE AD_Field SET SeqNo=70, SeqNoGrid=50,Updated=TO_TIMESTAMP('2023-12-20 11:04:55','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208091
;
-- Dec 20, 2023, 11:05:01 AM MYT
UPDATE AD_Field SET SeqNo=60, SeqNoGrid=40,Updated=TO_TIMESTAMP('2023-12-20 11:05:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208090
;
-- Dec 20, 2023, 11:05:13 AM MYT
UPDATE AD_Field SET SeqNo=50, SeqNoGrid=30,Updated=TO_TIMESTAMP('2023-12-20 11:05:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=208087
;
-- Dec 20, 2023, 11:05:55 AM MYT
INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (208095,'Column','Column in the table','Link to the database column of the table',200381,216305,'Y',0,40,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2023-12-20 11:05:55','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2023-12-20 11:05:55','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','57c973c1-cf9b-44cb-a150-61c706a1479d','Y',20,4,2,1,'N','N','N','N')
;

View File

@ -44,6 +44,7 @@ Export-Package: bsh,
org.compiere,
org.compiere.acct,
org.compiere.db,
org.compiere.db.partition,
org.compiere.dbPort,
org.compiere.impexp,
org.compiere.install,

View File

@ -25,6 +25,7 @@ import java.sql.Timestamp;
import javax.sql.DataSource;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.dbPort.Convert;
import org.compiere.model.MColumn;
import org.compiere.model.MTable;
@ -496,5 +497,13 @@ public interface AdempiereDatabase
public default boolean isQueryTimeout(SQLException ex) {
return ex instanceof SQLTimeoutException;
}
/**
* Get DB specific table partition support
* @return ITablePartitionService instance
*/
public default ITablePartitionService getTablePartitionService() {
return null;
}
} // AdempiereDatabase

View File

@ -0,0 +1,69 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Elaine Tan - etantg *
**********************************************************************/
package org.compiere.db.partition;
import org.compiere.model.MColumn;
import org.compiere.model.MTable;
import org.compiere.process.ProcessInfo;
/**
* Interface to support partition table
*/
public interface ITablePartitionService {
/**
* @return true if table have been partition in DB
*/
public boolean isPartitionedTable(MTable table, String trxName);
/**
* Make existing table a partition table
* @return true if success
*/
public boolean createPartitionedTable(MTable table, String trxName, ProcessInfo processInfo);
/**
* Add new partition for new data and migrate data to new partition (if needed by DB)
* @return true if success
*/
public boolean addPartitionAndMigrateData(MTable table, String trxName, ProcessInfo processInfo);
/**
* Run post partition process (if needed)
* @return true if success
*/
public boolean runPostPartitionProcess(MTable table, String trxName, ProcessInfo processInfo);
/**
* Validate partition configuration for table object
* @return String error-code - null if not error
*/
public String isValidConfiguration(MTable table);
/**
* Validate partition configuration for column object
* @return String error-code - null if not error
*/
public String isValidConfiguration(MColumn column);
}

View File

@ -0,0 +1,74 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.compiere.db.partition;
/**
* Value object for a range partition column
*/
public class RangePartitionColumn {
private String columnName;
private String intervalPattern;
private Object minValue;
private Object maxValue;
/**
* @param columnName
* @param intervalPattern
* @param minValue
* @param maxValue
*/
public RangePartitionColumn(String columnName, String intervalPattern, Object minValue, Object maxValue)
{
this.columnName = columnName;
this.intervalPattern = intervalPattern;
this.minValue = minValue;
this.maxValue = maxValue;
}
/**
* @return column name
*/
public String getColumnName() {
return columnName;
}
/**
* @return interval pattern for range
*/
public String getIntervalPattern() {
return intervalPattern;
}
/**
* @return minimum value of range
*/
public Object getMinValue() {
return minValue;
}
/**
* @return maximum value of range
*/
public Object getMaxValue() {
return maxValue;
}
}

View File

@ -0,0 +1,234 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.compiere.db.partition;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.compiere.model.MColumn;
import org.compiere.model.MTable;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
public class RangePartitionInterval {
private String columnName;
private String name;
private Object from;
private Object to;
private static Pattern yearMonthPattern = Pattern.compile("^([1-9]{1}[0-9]?)\\s+year(?:s)?\\s+([1-9]{1}[0-9]?)\\s+month(?:s)?$");
private static Pattern yearPattern = Pattern.compile("^([1-9]{1}[0-9]?)\\s+(year)(?:s)?$");
private static Pattern monthPattern = Pattern.compile("^([1-9]{1}[0-9]?)\\s+(month)(?:s)?$");
/**
* @param name
* @param from
* @param to
*/
public RangePartitionInterval(String columnName, String name, Object from, Object to)
{
this.columnName = columnName;
this.name = name;
this.from = from;
this.to = to;
}
/**
* @return column name
*/
public String getColumnName() {
return columnName;
}
/**
* @return interval name
*/
public String getName() {
return name;
}
/**
* @return interval from value
*/
public Object getFrom() {
return from;
}
/**
* @return interval to value
*/
public Object getTo() {
return to;
}
/**
* Validate range partition interval pattern
* @param column
* @return String error-code - null if not error
*/
public static String validateIntervalPattern(MColumn column) {
if (DisplayType.isDate(column.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(column.getAD_Reference_ID()))
{
Matcher matcher = yearMonthPattern.matcher(column.getRangePartitionInterval());
if (!matcher.matches())
{
matcher = yearPattern.matcher(column.getRangePartitionInterval());
if (!matcher.matches())
{
matcher = monthPattern.matcher(column.getRangePartitionInterval());
if (!matcher.matches())
return Msg.getMsg(Env.getCtx(), "InvalidRangePartitionInterval");
return null;
}
return null;
}
return null;
}
else if (DisplayType.isNumeric(column.getAD_Reference_ID()) || DisplayType.isID(column.getAD_Reference_ID()))
{
Pattern pattern = Pattern.compile("^[1-9]\\d*$");
Matcher matcher = pattern.matcher(column.getRangePartitionInterval());
if (!matcher.matches())
return Msg.getMsg(Env.getCtx(), "InvalidRangePartitionInterval");
return null;
}
else
return Msg.getMsg(Env.getCtx(), "RangePartitionKeyTypeNotSupported");
}
/**
* @param table
* @param rangePartitionColumn
* @param trxName
* @return RangePartitionInterval
*/
public static List<RangePartitionInterval> createInterval(MTable table, RangePartitionColumn rangePartitionColumn, String trxName) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
MColumn partitionKeyColumn = table.getColumn(rangePartitionColumn.getColumnName());
List<RangePartitionInterval> rangePartitionIntervals = new ArrayList<>();
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
{
Interval interval = getInterval(partitionKeyColumn);
Timestamp minValue = (Timestamp) rangePartitionColumn.getMinValue();
Timestamp maxValue = (Timestamp) rangePartitionColumn.getMaxValue();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(minValue.getTime());
cal.set(cal.get(Calendar.YEAR), (interval.months > 0) ? cal.get(Calendar.MONTH) : 0, 1);
Calendar cal2 = Calendar.getInstance();
cal2.setTimeInMillis(maxValue.getTime());
while (cal.before(cal2))
{
String name = cal.get(Calendar.YEAR) +
(interval.months > 0 ? (cal.get(Calendar.MONTH)+1) >=10 ? "_" + (cal.get(Calendar.MONTH)+1)
: "_0" + (cal.get(Calendar.MONTH)+1) : "");
String from = dateFormat.format(cal.getTime());
cal.add(Calendar.YEAR, interval.years);
cal.add(Calendar.MONTH, interval.months);
String to = dateFormat.format(cal.getTime());
RangePartitionInterval rangePartitionInterval = new RangePartitionInterval(rangePartitionColumn.getColumnName(), name, "'" + from + "'", "'" + to + "'");
rangePartitionIntervals.add(rangePartitionInterval);
}
}
else if (DisplayType.isNumeric(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isID(partitionKeyColumn.getAD_Reference_ID()))
{
Pattern pattern = Pattern.compile("^[1-9]\\d*$");
Matcher matcher = pattern.matcher(rangePartitionColumn.getIntervalPattern());
if (!matcher.matches())
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "InvalidRangePartitionInterval") + " [" + partitionKeyColumn + "]");
BigDecimal interval = new BigDecimal(rangePartitionColumn.getIntervalPattern());
BigDecimal minValue = (BigDecimal) rangePartitionColumn.getMinValue();
BigDecimal maxValue = (BigDecimal) rangePartitionColumn.getMaxValue();
BigDecimal value = minValue.divide(interval).setScale(0, RoundingMode.DOWN).multiply(interval);
while (value.compareTo(maxValue) <= 0)
{
String name = String.valueOf(value.intValue());
BigDecimal from = value;
value = value.add(interval);
BigDecimal to = value;
RangePartitionInterval rangePartitionInterval = new RangePartitionInterval(rangePartitionColumn.getColumnName(), name, from, to);
rangePartitionIntervals.add(rangePartitionInterval);
}
}
else
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "RangePartitionKeyTypeNotSupported") + " [" + partitionKeyColumn + "]");
return rangePartitionIntervals;
}
/**
* Get year and month interval from AD_Column.RangePartitionInterval.<br/>
* Throw exception if pattern is invalid.
* @param partitionKeyColumn
* @return year and month interval
*/
public static Interval getInterval(MColumn partitionKeyColumn) {
int years = 0;
int months = 0;
Matcher matcher = yearMonthPattern.matcher(partitionKeyColumn.getRangePartitionInterval());
if (matcher.matches())
{
years = Integer.parseInt(matcher.group(1));
months = Integer.parseInt(matcher.group(2));
}
else
{
matcher = yearPattern.matcher(partitionKeyColumn.getRangePartitionInterval());
if (matcher.matches())
years = Integer.parseInt(matcher.group(1));
else
{
matcher = monthPattern.matcher(partitionKeyColumn.getRangePartitionInterval());
if (matcher.matches())
months = Integer.parseInt(matcher.group(1));
}
}
if (years < 0 || months < 0 || (years == 0 && months == 0))
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "InvalidRangePartitionInterval") + " [" + partitionKeyColumn + "]");
return new Interval(years, months);
}
/**
* Year and month interval
*/
public static record Interval(int years, int months) {
}
}

View File

@ -539,6 +539,19 @@ s active status or processed status. This logic Applicable only if Always Updata
*/
public boolean isParent();
/** Column name IsPartitionKey */
public static final String COLUMNNAME_IsPartitionKey = "IsPartitionKey";
/** Set Partition Key.
* This is a partition key
*/
public void setIsPartitionKey (boolean IsPartitionKey);
/** Get Partition Key.
* This is a partition key
*/
public boolean isPartitionKey();
/** Column name IsSecure */
public static final String COLUMNNAME_IsSecure = "IsSecure";
@ -650,6 +663,19 @@ s active status or processed status. This logic Applicable only if Always Updata
public org.compiere.model.I_PA_DashboardContent getPA_DashboardContent() throws RuntimeException;
/** Column name PartitioningMethod */
public static final String COLUMNNAME_PartitioningMethod = "PartitioningMethod";
/** Set Partitioning Method.
* Indicates how the Table is partitioned
*/
public void setPartitioningMethod (String PartitioningMethod);
/** Get Partitioning Method.
* Indicates how the Table is partitioned
*/
public String getPartitioningMethod();
/** Column name Placeholder */
public static final String COLUMNNAME_Placeholder = "Placeholder";
@ -659,6 +685,19 @@ s active status or processed status. This logic Applicable only if Always Updata
/** Get Placeholder */
public String getPlaceholder();
/** Column name RangePartitionInterval */
public static final String COLUMNNAME_RangePartitionInterval = "RangePartitionInterval";
/** Set Range Partition Interval.
* Indicates the interval used in a range partitioning
*/
public void setRangePartitionInterval (String RangePartitionInterval);
/** Get Range Partition Interval.
* Indicates the interval used in a range partitioning
*/
public String getRangePartitionInterval();
/** Column name ReadOnlyLogic */
public static final String COLUMNNAME_ReadOnlyLogic = "ReadOnlyLogic";
@ -687,6 +726,19 @@ s active status or processed status. This logic Applicable only if Always Updata
*/
public int getSeqNo();
/** Column name SeqNoPartition */
public static final String COLUMNNAME_SeqNoPartition = "SeqNoPartition";
/** Set Partition Key Sequence.
* Indicates the order of partition keys
*/
public void setSeqNoPartition (int SeqNoPartition);
/** Get Partition Key Sequence.
* Indicates the order of partition keys
*/
public int getSeqNoPartition();
/** Column name SeqNoSelection */
public static final String COLUMNNAME_SeqNoSelection = "SeqNoSelection";

View File

@ -161,6 +161,19 @@ public interface I_AD_Table
*/
public int getCreatedBy();
/** Column name CreatePartition */
public static final String COLUMNNAME_CreatePartition = "CreatePartition";
/** Set Create/update partition.
* Process which create or update table partitions based on the table and column records
*/
public void setCreatePartition (String CreatePartition);
/** Get Create/update partition.
* Process which create or update table partitions based on the table and column records
*/
public String getCreatePartition();
/** Column name CreateWindowFromTable */
public static final String COLUMNNAME_CreateWindowFromTable = "CreateWindowFromTable";
@ -298,6 +311,19 @@ public interface I_AD_Table
*/
public boolean isHighVolume();
/** Column name IsPartition */
public static final String COLUMNNAME_IsPartition = "IsPartition";
/** Set Partition.
* This is a partitioned table
*/
public void setIsPartition (boolean IsPartition);
/** Get Partition.
* This is a partitioned table
*/
public boolean isPartition();
/** Column name IsSecurityEnabled */
public static final String COLUMNNAME_IsSecurityEnabled = "IsSecurityEnabled";

View File

@ -0,0 +1,187 @@
/******************************************************************************
* Product: iDempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2012 ComPiere, Inc. All Rights Reserved. *
* This program is free software, you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY, without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program, if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
package org.compiere.model;
import java.math.BigDecimal;
import java.sql.Timestamp;
import org.compiere.util.KeyNamePair;
/** Generated Interface for AD_TablePartition
* @author iDempiere (generated)
* @version Release 11
*/
public interface I_AD_TablePartition
{
/** TableName=AD_TablePartition */
public static final String Table_Name = "AD_TablePartition";
/** AD_Table_ID=200411 */
public static final int Table_ID = 200411;
KeyNamePair Model = new KeyNamePair(Table_ID, Table_Name);
/** AccessLevel = 4 - System
*/
BigDecimal accessLevel = BigDecimal.valueOf(4);
/** Load Meta Data */
/** Column name AD_Client_ID */
public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID";
/** Get Tenant.
* Tenant for this installation.
*/
public int getAD_Client_ID();
/** Column name AD_Column_ID */
public static final String COLUMNNAME_AD_Column_ID = "AD_Column_ID";
/** Set Column.
* Column in the table
*/
public void setAD_Column_ID (int AD_Column_ID);
/** Get Column.
* Column in the table
*/
public int getAD_Column_ID();
public org.compiere.model.I_AD_Column getAD_Column() throws RuntimeException;
/** Column name AD_Org_ID */
public static final String COLUMNNAME_AD_Org_ID = "AD_Org_ID";
/** Set Organization.
* Organizational entity within tenant
*/
public void setAD_Org_ID (int AD_Org_ID);
/** Get Organization.
* Organizational entity within tenant
*/
public int getAD_Org_ID();
/** Column name AD_Table_ID */
public static final String COLUMNNAME_AD_Table_ID = "AD_Table_ID";
/** Set Table.
* Database Table information
*/
public void setAD_Table_ID (int AD_Table_ID);
/** Get Table.
* Database Table information
*/
public int getAD_Table_ID();
public org.compiere.model.I_AD_Table getAD_Table() throws RuntimeException;
/** Column name AD_TablePartition_ID */
public static final String COLUMNNAME_AD_TablePartition_ID = "AD_TablePartition_ID";
/** Set Table Partition.
* Database Table Partition information
*/
public void setAD_TablePartition_ID (int AD_TablePartition_ID);
/** Get Table Partition.
* Database Table Partition information
*/
public int getAD_TablePartition_ID();
/** Column name AD_TablePartition_UU */
public static final String COLUMNNAME_AD_TablePartition_UU = "AD_TablePartition_UU";
/** Set AD_TablePartition_UU */
public void setAD_TablePartition_UU (String AD_TablePartition_UU);
/** Get AD_TablePartition_UU */
public String getAD_TablePartition_UU();
/** Column name Created */
public static final String COLUMNNAME_Created = "Created";
/** Get Created.
* Date this record was created
*/
public Timestamp getCreated();
/** Column name CreatedBy */
public static final String COLUMNNAME_CreatedBy = "CreatedBy";
/** Get Created By.
* User who created this records
*/
public int getCreatedBy();
/** Column name ExpressionPartition */
public static final String COLUMNNAME_ExpressionPartition = "ExpressionPartition";
/** Set Expression.
* SQL clause for partition
*/
public void setExpressionPartition (String ExpressionPartition);
/** Get Expression.
* SQL clause for partition
*/
public String getExpressionPartition();
/** Column name IsActive */
public static final String COLUMNNAME_IsActive = "IsActive";
/** Set Active.
* The record is active in the system
*/
public void setIsActive (boolean IsActive);
/** Get Active.
* The record is active in the system
*/
public boolean isActive();
/** Column name Name */
public static final String COLUMNNAME_Name = "Name";
/** Set Name.
* Alphanumeric identifier of the entity
*/
public void setName (String Name);
/** Get Name.
* Alphanumeric identifier of the entity
*/
public String getName();
/** Column name Updated */
public static final String COLUMNNAME_Updated = "Updated";
/** Get Updated.
* Date this record was updated
*/
public Timestamp getUpdated();
/** Column name UpdatedBy */
public static final String COLUMNNAME_UpdatedBy = "UpdatedBy";
/** Get Updated By.
* User who updated this records
*/
public int getUpdatedBy();
}

View File

@ -33,6 +33,7 @@ import java.util.Properties;
import org.adempiere.exceptions.DBException;
import org.compiere.db.AdempiereDatabase;
import org.compiere.db.Database;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
@ -579,6 +580,30 @@ public class MColumn extends X_AD_Column implements ImmutablePOSupport
setDefaultValue("N");
}
}
if (isActive() && isPartitionKey() && getSeqNoPartition() <= 0)
{
String sql = "SELECT COALESCE(MAX(SeqNoPartition),0)+10 AS DefaultValue FROM AD_Column WHERE AD_Table_ID=? AND IsActive='Y' AND IsPartitionKey='Y'";
int ii = DB.getSQLValue(get_TrxName(), sql, getAD_Table_ID());
setSeqNoPartition(ii);
}
if (is_ValueChanged(COLUMNNAME_IsPartitionKey)
|| is_ValueChanged(COLUMNNAME_PartitioningMethod)
|| (isPartitionKey() && is_ValueChanged(COLUMNNAME_IsActive))
|| (isPartitionKey() && is_ValueChanged(COLUMNNAME_SeqNoPartition))
|| (isPartitionKey() && is_ValueChanged(COLUMNNAME_RangePartitionInterval))) {
ITablePartitionService service = DB.getDatabase().getTablePartitionService();
if (service == null) {
log.saveError("Error", Msg.getMsg(getCtx(), "DBAdapterNoTablePartitionSupport"));
return false;
}
error = service.isValidConfiguration(this);
if (!Util.isEmpty(error)) {
log.saveError("Error", Msg.getMsg(getCtx(), error));
return false;
}
}
return true;
} // beforeSave

View File

@ -35,6 +35,7 @@ import org.adempiere.base.Service;
import org.adempiere.model.GenericPO;
import org.compiere.db.AdempiereDatabase;
import org.compiere.db.Database;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.util.CCache;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
@ -762,6 +763,20 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport
log.saveError("Error", Msg.getMsg(getCtx(), error) + " [TableName]");
return false;
}
if (is_ValueChanged(COLUMNNAME_IsPartition)) {
ITablePartitionService service = DB.getDatabase().getTablePartitionService();
if (service == null) {
log.saveError("Error", Msg.getMsg(getCtx(), "DBAdapterNoTablePartitionSupport"));
return false;
}
error = service.isValidConfiguration(this);
if (!Util.isEmpty(error)) {
log.saveError("Error", Msg.getMsg(getCtx(), error));
return false;
}
}
return true;
} // beforeSave
@ -941,4 +956,116 @@ public class MTable extends X_AD_Table implements ImmutablePOSupport
return uuidFromZeroID;
}
private List<MColumn> partitionKeyColumns;
private List<String> partitionKeyColumnNames;
/**
* @param requery true to reload from DB
* @return partition key columns
*/
public List<MColumn> getPartitionKeyColumns(boolean requery)
{
if (partitionKeyColumns != null && !requery)
return partitionKeyColumns;
partitionKeyColumnNames = null;
String whereClause = MColumn.COLUMNNAME_AD_Table_ID + "=? AND " + MColumn.COLUMNNAME_IsPartitionKey + "='Y'";
partitionKeyColumns = new Query(getCtx(), MColumn.Table_Name, whereClause, null)
.setParameters(getAD_Table_ID())
.setOnlyActiveRecords(true)
.setOrderBy(MColumn.COLUMNNAME_SeqNoPartition)
.list();
return partitionKeyColumns;
}
/**
* Update {@link #partitionKeyColumnNames} and {@link #partitionKeyColumnNamesAsString}
*/
private void populatePartitionKeyColumnNames()
{
List<MColumn> keyColumns = getPartitionKeyColumns(false);
partitionKeyColumnNames = new ArrayList<String>();
StringBuilder keyColumnsString = new StringBuilder();
int columnCount = 0;
for (MColumn keyColumn : keyColumns)
{
if (columnCount > 0)
keyColumnsString.append(",");
keyColumnsString.append(keyColumn.getColumnName());
partitionKeyColumnNames.add(keyColumn.getColumnName());
++columnCount;
}
}
/**
* @return partition key column names
*/
public List<String> getPartitionKeyColumnNames()
{
if (partitionKeyColumnNames != null)
return partitionKeyColumnNames;
populatePartitionKeyColumnNames();
return partitionKeyColumnNames;
}
/**
* Create and save new X_AD_TablePartition record.
* @param name
* @param expression
* @param trxName
* @param column
* @return new X_AD_TablePartition record
*/
public X_AD_TablePartition createTablePartition(String name, String expression, String trxName, MColumn column)
{
X_AD_TablePartition partition = new X_AD_TablePartition(Env.getCtx(), 0, trxName);
partition.setAD_Table_ID(getAD_Table_ID());
partition.setName(name);
partition.setExpressionPartition(expression);
partition.setAD_Column_ID(column.getAD_Column_ID());
partition.saveEx();
return partition;
}
private List<X_AD_TablePartition> tablePartitions;
private List<String> tablePartitionNames;
/**
* @param requery true to reload from DB
* @param trxName
* @return X_AD_TablePartition records of this table
*/
public List<X_AD_TablePartition> getTablePartitions(boolean requery, String trxName)
{
if (tablePartitions != null && !requery)
return tablePartitions;
tablePartitionNames = null;
String whereClause = X_AD_TablePartition.COLUMNNAME_AD_Table_ID + "=?";
tablePartitions = new Query(getCtx(), X_AD_TablePartition.Table_Name, whereClause, trxName)
.setParameters(getAD_Table_ID())
.setOnlyActiveRecords(true)
.setOrderBy(X_AD_TablePartition.COLUMNNAME_Name)
.list();
return tablePartitions;
}
/**
* @param trxName
* @return list of table partition name
*/
public List<String> getTablePartitionNames(String trxName)
{
if (tablePartitionNames != null)
return tablePartitionNames;
List<X_AD_TablePartition> partitions = getTablePartitions(false, trxName);
tablePartitionNames = new ArrayList<String>();
for (X_AD_TablePartition partition : partitions)
tablePartitionNames.add(partition.getName());
return tablePartitionNames;
}
} // MTable

View File

@ -33,7 +33,7 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
/**
*
*/
private static final long serialVersionUID = 20231019L;
private static final long serialVersionUID = 20231213L;
/** Standard Constructor */
public X_AD_Column (Properties ctx, int AD_Column_ID, String trxName)
@ -60,6 +60,8 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
setIsKey (false);
setIsMandatory (false);
setIsParent (false);
setIsPartitionKey (false);
// 'N'
setIsSecure (false);
// N
setIsSelectionColumn (false);
@ -98,6 +100,8 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
setIsKey (false);
setIsMandatory (false);
setIsParent (false);
setIsPartitionKey (false);
// 'N'
setIsSecure (false);
// N
setIsSelectionColumn (false);
@ -136,6 +140,8 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
setIsKey (false);
setIsMandatory (false);
setIsParent (false);
setIsPartitionKey (false);
// 'N'
setIsSecure (false);
// N
setIsSelectionColumn (false);
@ -174,6 +180,8 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
setIsKey (false);
setIsMandatory (false);
setIsParent (false);
setIsPartitionKey (false);
// 'N'
setIsSecure (false);
// N
setIsSelectionColumn (false);
@ -981,6 +989,29 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
return false;
}
/** Set Partition Key.
@param IsPartitionKey This is a partition key
*/
public void setIsPartitionKey (boolean IsPartitionKey)
{
set_Value (COLUMNNAME_IsPartitionKey, Boolean.valueOf(IsPartitionKey));
}
/** Get Partition Key.
@return This is a partition key
*/
public boolean isPartitionKey()
{
Object oo = get_Value(COLUMNNAME_IsPartitionKey);
if (oo != null)
{
if (oo instanceof Boolean)
return ((Boolean)oo).booleanValue();
return "Y".equals(oo);
}
return false;
}
/** Set Secure content.
@param IsSecure Defines whether content must be treated as secure
*/
@ -1171,6 +1202,28 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
return 0;
return ii.intValue();
}
/** PartitioningMethod AD_Reference_ID=200261 */
public static final int PARTITIONINGMETHOD_AD_Reference_ID=200261;
/** List = L */
public static final String PARTITIONINGMETHOD_List = "L";
/** Range = R */
public static final String PARTITIONINGMETHOD_Range = "R";
/** Set Partitioning Method.
@param PartitioningMethod Indicates how the Table is partitioned
*/
public void setPartitioningMethod (String PartitioningMethod)
{
set_Value (COLUMNNAME_PartitioningMethod, PartitioningMethod);
}
/** Get Partitioning Method.
@return Indicates how the Table is partitioned
*/
public String getPartitioningMethod()
{
return (String)get_Value(COLUMNNAME_PartitioningMethod);
}
/** Set Placeholder.
@param Placeholder Placeholder
@ -1187,6 +1240,22 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
return (String)get_Value(COLUMNNAME_Placeholder);
}
/** Set Range Partition Interval.
@param RangePartitionInterval Indicates the interval used in a range partitioning
*/
public void setRangePartitionInterval (String RangePartitionInterval)
{
set_Value (COLUMNNAME_RangePartitionInterval, RangePartitionInterval);
}
/** Get Range Partition Interval.
@return Indicates the interval used in a range partitioning
*/
public String getRangePartitionInterval()
{
return (String)get_Value(COLUMNNAME_RangePartitionInterval);
}
/** Set Read Only Logic.
@param ReadOnlyLogic Logic to determine if field is read only (applies only when field is read-write)
*/
@ -1222,6 +1291,25 @@ public class X_AD_Column extends PO implements I_AD_Column, I_Persistent
return ii.intValue();
}
/** Set Partition Key Sequence.
@param SeqNoPartition Indicates the order of partition keys
*/
public void setSeqNoPartition (int SeqNoPartition)
{
set_Value (COLUMNNAME_SeqNoPartition, Integer.valueOf(SeqNoPartition));
}
/** Get Partition Key Sequence.
@return Indicates the order of partition keys
*/
public int getSeqNoPartition()
{
Integer ii = (Integer)get_Value(COLUMNNAME_SeqNoPartition);
if (ii == null)
return 0;
return ii.intValue();
}
/** Set Selection Column Sequence.
@param SeqNoSelection Selection Column Sequence
*/

View File

@ -31,7 +31,7 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
/**
*
*/
private static final long serialVersionUID = 20230409L;
private static final long serialVersionUID = 20231213L;
/** Standard Constructor */
public X_AD_Table (Properties ctx, int AD_Table_ID, String trxName)
@ -49,6 +49,8 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
setIsDeleteable (true);
// Y
setIsHighVolume (false);
setIsPartition (false);
// N
setIsSecurityEnabled (false);
setIsView (false);
// N
@ -75,6 +77,8 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
setIsDeleteable (true);
// Y
setIsHighVolume (false);
setIsPartition (false);
// N
setIsSecurityEnabled (false);
setIsView (false);
// N
@ -101,6 +105,8 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
setIsDeleteable (true);
// Y
setIsHighVolume (false);
setIsPartition (false);
// N
setIsSecurityEnabled (false);
setIsView (false);
// N
@ -127,6 +133,8 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
setIsDeleteable (true);
// Y
setIsHighVolume (false);
setIsPartition (false);
// N
setIsSecurityEnabled (false);
setIsView (false);
// N
@ -319,6 +327,22 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
return (String)get_Value(COLUMNNAME_CopyComponentsFromView);
}
/** Set Create/update partition.
@param CreatePartition Process which create or update table partitions based on the table and column records
*/
public void setCreatePartition (String CreatePartition)
{
set_Value (COLUMNNAME_CreatePartition, CreatePartition);
}
/** Get Create/update partition.
@return Process which create or update table partitions based on the table and column records
*/
public String getCreatePartition()
{
return (String)get_Value(COLUMNNAME_CreatePartition);
}
/** Set Create Window From Table.
@param CreateWindowFromTable Create Window From Table
*/
@ -508,6 +532,29 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
return false;
}
/** Set Partition.
@param IsPartition This is a partitioned table
*/
public void setIsPartition (boolean IsPartition)
{
set_Value (COLUMNNAME_IsPartition, Boolean.valueOf(IsPartition));
}
/** Get Partition.
@return This is a partitioned table
*/
public boolean isPartition()
{
Object oo = get_Value(COLUMNNAME_IsPartition);
if (oo != null)
{
if (oo instanceof Boolean)
return ((Boolean)oo).booleanValue();
return "Y".equals(oo);
}
return false;
}
/** Set Security enabled.
@param IsSecurityEnabled If security is enabled, user access to data can be restricted via Roles
*/
@ -610,7 +657,7 @@ public class X_AD_Table extends PO implements I_AD_Table, I_Persistent
{
return (String)get_Value(COLUMNNAME_Name);
}
public org.compiere.model.I_AD_Window getPO_Window() throws RuntimeException
{
return (org.compiere.model.I_AD_Window)MTable.get(getCtx(), org.compiere.model.I_AD_Window.Table_ID)

View File

@ -0,0 +1,239 @@
/******************************************************************************
* Product: iDempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2012 ComPiere, Inc. All Rights Reserved. *
* This program is free software, you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY, without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program, if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
/** Generated Model - DO NOT CHANGE */
package org.compiere.model;
import java.sql.ResultSet;
import java.util.Properties;
/** Generated Model for AD_TablePartition
* @author iDempiere (generated)
* @version Release 11 - $Id$ */
@org.adempiere.base.Model(table="AD_TablePartition")
public class X_AD_TablePartition extends PO implements I_AD_TablePartition, I_Persistent
{
/**
*
*/
private static final long serialVersionUID = 20231220L;
/** Standard Constructor */
public X_AD_TablePartition (Properties ctx, int AD_TablePartition_ID, String trxName)
{
super (ctx, AD_TablePartition_ID, trxName);
/** if (AD_TablePartition_ID == 0)
{
setAD_Column_ID (0);
setAD_Table_ID (0);
setExpressionPartition (null);
setName (null);
} */
}
/** Standard Constructor */
public X_AD_TablePartition (Properties ctx, int AD_TablePartition_ID, String trxName, String ... virtualColumns)
{
super (ctx, AD_TablePartition_ID, trxName, virtualColumns);
/** if (AD_TablePartition_ID == 0)
{
setAD_Column_ID (0);
setAD_Table_ID (0);
setExpressionPartition (null);
setName (null);
} */
}
/** Standard Constructor */
public X_AD_TablePartition (Properties ctx, String AD_TablePartition_UU, String trxName)
{
super (ctx, AD_TablePartition_UU, trxName);
/** if (AD_TablePartition_UU == null)
{
setAD_Column_ID (0);
setAD_Table_ID (0);
setExpressionPartition (null);
setName (null);
} */
}
/** Standard Constructor */
public X_AD_TablePartition (Properties ctx, String AD_TablePartition_UU, String trxName, String ... virtualColumns)
{
super (ctx, AD_TablePartition_UU, trxName, virtualColumns);
/** if (AD_TablePartition_UU == null)
{
setAD_Column_ID (0);
setAD_Table_ID (0);
setExpressionPartition (null);
setName (null);
} */
}
/** Load Constructor */
public X_AD_TablePartition (Properties ctx, ResultSet rs, String trxName)
{
super (ctx, rs, trxName);
}
/** AccessLevel
* @return 4 - System
*/
protected int get_AccessLevel()
{
return accessLevel.intValue();
}
/** Load Meta Data */
protected POInfo initPO (Properties ctx)
{
POInfo poi = POInfo.getPOInfo (ctx, Table_ID, get_TrxName());
return poi;
}
public String toString()
{
StringBuilder sb = new StringBuilder ("X_AD_TablePartition[")
.append(get_ID()).append(",Name=").append(getName()).append("]");
return sb.toString();
}
public org.compiere.model.I_AD_Column getAD_Column() throws RuntimeException
{
return (org.compiere.model.I_AD_Column)MTable.get(getCtx(), org.compiere.model.I_AD_Column.Table_ID)
.getPO(getAD_Column_ID(), get_TrxName());
}
/** Set Column.
@param AD_Column_ID Column in the table
*/
public void setAD_Column_ID (int AD_Column_ID)
{
if (AD_Column_ID < 1)
set_ValueNoCheck (COLUMNNAME_AD_Column_ID, null);
else
set_ValueNoCheck (COLUMNNAME_AD_Column_ID, Integer.valueOf(AD_Column_ID));
}
/** Get Column.
@return Column in the table
*/
public int getAD_Column_ID()
{
Integer ii = (Integer)get_Value(COLUMNNAME_AD_Column_ID);
if (ii == null)
return 0;
return ii.intValue();
}
public org.compiere.model.I_AD_Table getAD_Table() throws RuntimeException
{
return (org.compiere.model.I_AD_Table)MTable.get(getCtx(), org.compiere.model.I_AD_Table.Table_ID)
.getPO(getAD_Table_ID(), get_TrxName());
}
/** Set Table.
@param AD_Table_ID Database Table information
*/
public void setAD_Table_ID (int AD_Table_ID)
{
if (AD_Table_ID < 1)
set_ValueNoCheck (COLUMNNAME_AD_Table_ID, null);
else
set_ValueNoCheck (COLUMNNAME_AD_Table_ID, Integer.valueOf(AD_Table_ID));
}
/** Get Table.
@return Database Table information
*/
public int getAD_Table_ID()
{
Integer ii = (Integer)get_Value(COLUMNNAME_AD_Table_ID);
if (ii == null)
return 0;
return ii.intValue();
}
/** Set Table Partition.
@param AD_TablePartition_ID Database Table Partition information
*/
public void setAD_TablePartition_ID (int AD_TablePartition_ID)
{
if (AD_TablePartition_ID < 1)
set_ValueNoCheck (COLUMNNAME_AD_TablePartition_ID, null);
else
set_ValueNoCheck (COLUMNNAME_AD_TablePartition_ID, Integer.valueOf(AD_TablePartition_ID));
}
/** Get Table Partition.
@return Database Table Partition information
*/
public int getAD_TablePartition_ID()
{
Integer ii = (Integer)get_Value(COLUMNNAME_AD_TablePartition_ID);
if (ii == null)
return 0;
return ii.intValue();
}
/** Set AD_TablePartition_UU.
@param AD_TablePartition_UU AD_TablePartition_UU
*/
public void setAD_TablePartition_UU (String AD_TablePartition_UU)
{
set_ValueNoCheck (COLUMNNAME_AD_TablePartition_UU, AD_TablePartition_UU);
}
/** Get AD_TablePartition_UU.
@return AD_TablePartition_UU */
public String getAD_TablePartition_UU()
{
return (String)get_Value(COLUMNNAME_AD_TablePartition_UU);
}
/** Set Expression.
@param ExpressionPartition SQL clause for partition
*/
public void setExpressionPartition (String ExpressionPartition)
{
set_Value (COLUMNNAME_ExpressionPartition, ExpressionPartition);
}
/** Get Expression.
@return SQL clause for partition
*/
public String getExpressionPartition()
{
return (String)get_Value(COLUMNNAME_ExpressionPartition);
}
/** Set Name.
@param Name Alphanumeric identifier of the entity
*/
public void setName (String Name)
{
set_Value (COLUMNNAME_Name, Name);
}
/** Get Name.
@return Alphanumeric identifier of the entity
*/
public String getName()
{
return (String)get_Value(COLUMNNAME_Name);
}
}

View File

@ -443,8 +443,10 @@
<setEntry value="org.idempiere.jetty.osgi.boot.fragment@default:false"/>
<setEntry value="org.idempiere.keikai@default:false"/>
<setEntry value="org.idempiere.printformat.editor@default:default"/>
<setEntry value="org.idempiere.webservices@default:default"/>
<setEntry value="org.idempiere.tablepartition@default:default"/>
<setEntry value="org.idempiere.ui.sso.oidc@default:default"/>
<setEntry value="org.idempiere.webservices.resources@default:default"/>
<setEntry value="org.idempiere.webservices@default:default"/>
<setEntry value="org.idempiere.zk.billboard.chart@default:default"/>
<setEntry value="org.idempiere.zk.billboard@default:false"/>
<setEntry value="org.idempiere.zk.extra@default:default"/>

View File

@ -443,6 +443,7 @@
<setEntry value="org.idempiere.jetty.osgi.boot.fragment@default:false"/>
<setEntry value="org.idempiere.keikai@default:false"/>
<setEntry value="org.idempiere.printformat.editor@default:default"/>
<setEntry value="org.idempiere.tablepartition@default:default"/>
<setEntry value="org.idempiere.ui.sso.oidc@default:default"/>
<setEntry value="org.idempiere.webservices.resources@default:default"/>
<setEntry value="org.idempiere.webservices@default:default"/>

View File

@ -0,0 +1,648 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.adempiere.db.oracle.partition;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.db.partition.RangePartitionColumn;
import org.compiere.db.partition.RangePartitionInterval;
import org.compiere.model.MColumn;
import org.compiere.model.MTable;
import org.compiere.model.Query;
import org.compiere.model.X_AD_TablePartition;
import org.compiere.process.ProcessInfo;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
public class TablePartitionService implements ITablePartitionService {
//make the following 2 potentially configurable in future (just in case this is needed)
private boolean useAutomaticListPartition = true;
private boolean useIntervalPartition = true;
public TablePartitionService() {
}
@Override
public boolean isPartitionedTable(MTable table, String trxName) {
String sql =
"""
SELECT 1 FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = ?
""";
return DB.getSQLValueEx(trxName, sql, table.getTableName().toUpperCase()) == 1;
}
@Override
public boolean createPartitionedTable(MTable table, String trxName, ProcessInfo processInfo) {
StringBuilder alterStmt = new StringBuilder("ALTER TABLE ")
.append(table.getTableName())
.append(" MODIFY PARTITION BY ");
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
MColumn partitionKeyColumn = partitionKeyColumns.get(0);
String partitioningMethod = partitionKeyColumn.getPartitioningMethod();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List))
alterStmt.append("List");
else if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_Range))
alterStmt.append("Range");
else
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "PartitioningMethodNotSupported", new Object[]{partitioningMethod}));
alterStmt.append(" (" + partitionKeyColumn.getColumnName() + ")");
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List) && useAutomaticListPartition) {
//with automatic, we still need to create at least one partition and we will create a null partition to fulfill the requirement
alterStmt.append(" AUTOMATIC (PARTITION default_partition ");
} else if (useIntervalPartition) {
alterStmt.append(" INTERVAL(");
alterStmt.append(getIntervalExpression(partitionKeyColumn));
alterStmt.append(") (PARTITION default_partition ");
} else {
alterStmt.append(" (PARTITION default_partition ");
}
StringBuilder defaultExpression = new StringBuilder();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List)) {
defaultExpression.append("VALUES (");
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List) && useAutomaticListPartition)
defaultExpression.append("NULL");
else
defaultExpression.append("DEFAULT");
defaultExpression.append(")");
} else {
if (useIntervalPartition) {
if (alterStmt.indexOf("NUMTOYMINTERVAL(") > 0)
defaultExpression.append("VALUES LESS THAN (TO_DATE('1970-01-01','YYYY-MM-DD')");
else
defaultExpression.append("VALUES LESS THAN (").append("0");
} else {
defaultExpression.append("VALUES LESS THAN (");
defaultExpression.append("MAXVALUE");
}
defaultExpression.append(")");
}
alterStmt.append(defaultExpression.toString());
alterStmt.append(" ) ");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (processInfo != null)
processInfo.addLog(0, null, null, no + " " + alterStmt.toString());
if (!(partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List) && useAutomaticListPartition))
table.createTablePartition("default_partition", defaultExpression.toString(), trxName, partitionKeyColumn);
return true;
}
private String getIntervalExpression(MColumn partitionKeyColumn) {
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID())) {
RangePartitionInterval.Interval interval = RangePartitionInterval.getInterval(partitionKeyColumn);
if (interval.years() > 0) {
if (interval.months() == 0) {
return "NUMTOYMINTERVAL("+interval.years()+",'YEAR')";
} else {
int months = interval.months() + (interval.years() * 12);
return "NUMTOYMINTERVAL("+months+",'MONTH')";
}
} else {
return "NUMTOYMINTERVAL("+interval.months()+",'MONTH')";
}
} else if (DisplayType.isNumeric(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isID(partitionKeyColumn.getAD_Reference_ID())) {
Pattern pattern = Pattern.compile("^[1-9]\\d*$");
Matcher matcher = pattern.matcher(partitionKeyColumn.getRangePartitionInterval());
if (!matcher.matches())
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "InvalidRangePartitionInterval") + " [" + partitionKeyColumn + "]");
BigDecimal interval = new BigDecimal(partitionKeyColumn.getRangePartitionInterval());
return interval.toPlainString();
} else {
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "RangePartitionKeyTypeNotSupported") + " [" + partitionKeyColumn + "]");
}
}
@Override
public boolean addPartitionAndMigrateData(MTable table, String trxName, ProcessInfo processInfo) {
boolean isUpdated = false;
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
if (partitionKeyColumns.size() == 0)
return false;
MColumn partitionKeyColumn = partitionKeyColumns.get(0);
String sql = "SELECT Column_Name FROM User_Part_Key_Columns WHERE Name=? ORDER BY Column_Position";
String partKeyColumn = DB.getSQLValueString(trxName, sql, table.getTableName().toUpperCase());
if (!partitionKeyColumn.getColumnName().equalsIgnoreCase(partKeyColumn))
return false;
String partitioningMethod = partitionKeyColumn.getPartitioningMethod();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List))
{
if (isAutoList(table, trxName))
{
syncAutoList(table, partitionKeyColumn, trxName, processInfo);
syncPartition(table, trxName, processInfo, false);
}
else
{
isUpdated = addListPartition(table, partitionKeyColumn, trxName, processInfo);
}
}
else if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_Range))
{
if (!isRangePartitionedTable(table, trxName))
{
fromListToRange(table, trxName, processInfo, partitionKeyColumn);
syncPartition(table, trxName, processInfo, true);
}
else
{
String interval = getInterval(table, trxName);
if (!Util.isEmpty(interval, true))
{
syncInterval(table, partitionKeyColumn, trxName, interval, processInfo);
syncPartition(table, trxName, processInfo, true);
}
else
{
syncRange(table, partitionKeyColumn, trxName, interval, processInfo);
isUpdated = addRangePartition(table, partitionKeyColumn, trxName, processInfo);
}
}
}
else
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "PartitioningMethodNotSupported", new Object[]{partitioningMethod}));
return isUpdated;
}
/**
* Change partition method from list to range
* @param table
* @param trxName
* @param processInfo
* @param partitionKeyColumn
*/
private void fromListToRange(MTable table, String trxName, ProcessInfo processInfo, MColumn partitionKeyColumn) {
DB.executeUpdateEx("DELETE FROM AD_TablePartition WHERE AD_Table_ID=? AND Name=?", new Object[] {table.getAD_Table_ID(), "DEFAULT_PARTITION"}, trxName);
StringBuilder alterStmt = new StringBuilder("ALTER TABLE ")
.append(table.getTableName())
.append(" MODIFY PARTITION BY RANGE ")
.append(" (" + partitionKeyColumn.getColumnName() + ")");
if (useIntervalPartition) {
alterStmt.append(" INTERVAL(");
alterStmt.append(getIntervalExpression(partitionKeyColumn));
alterStmt.append(") (PARTITION default_partition ");
} else {
alterStmt.append(" (PARTITION default_partition ");
}
StringBuilder defaultExpression = new StringBuilder();
if (useIntervalPartition) {
if (alterStmt.indexOf("NUMTOYMINTERVAL(") > 0)
defaultExpression.append("VALUES LESS THAN (TO_DATE('1970-01-01','YYYY-MM-DD')");
else
defaultExpression.append("VALUES LESS THAN (").append("0");
} else {
defaultExpression.append("VALUES LESS THAN (");
defaultExpression.append("MAXVALUE");
}
defaultExpression.append(")");
alterStmt.append(defaultExpression.toString());
alterStmt.append(" ) ");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (processInfo != null)
processInfo.addLog(0, null, null, no + " " + alterStmt.toString());
}
/**
* Update automatic list partitioning of table if the DB column list is different from current AD_Column values
* @param table
* @param partitionKeyColumn
* @param trxName
* @param pi
*/
private void syncAutoList(MTable table, MColumn partitionKeyColumn, String trxName, ProcessInfo pi) {
String keyColumn = partitionKeyColumn.getColumnName();
String sql = "SELECT Column_Name FROM User_Part_Key_Columns WHERE Name=? ORDER BY Column_Position";
List<List<Object>> columnNames = DB.getSQLArrayObjectsEx(trxName, sql, table.getTableName().toUpperCase());
boolean notSync = false;
if (columnNames.size() != 1) {
notSync = true;
} else {
if (!keyColumn.equalsIgnoreCase(columnNames.get(0).get(0).toString()))
notSync = true;
}
if (notSync) {
StringBuilder alterStmt = new StringBuilder("ALTER TABLE ")
.append(table.getTableName())
.append(" MODIFY PARTITION BY List ");
alterStmt.append(" (" + keyColumn + ")");
alterStmt.append(" AUTOMATIC (PARTITION default_partition VALUES (");
alterStmt.append("NULL");
alterStmt.append("))");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
}
}
/**
* Update partition interval of table if it is not in sync with current AD_Column.RangePartitionInterval value
* @param table
* @param partitionKeyColumn
* @param trxName
* @param interval
* @param pi
*/
private void syncInterval(MTable table, MColumn partitionKeyColumn, String trxName, String interval, ProcessInfo pi) {
String sql = "SELECT Column_Name FROM User_Part_Key_Columns WHERE Name=? ORDER BY Column_Position";
String intervalColumn = DB.getSQLValueString(trxName, sql, table.getTableName().toUpperCase());
String expression = getIntervalExpression(partitionKeyColumn);
if (partitionKeyColumn.getColumnName().toUpperCase().equals(intervalColumn)) {
if (!interval.toUpperCase().equals(expression)) {
//note that this only effect new data inserted into table and will not change existing partition
sql = "ALTER TABLE " + table.getTableName() + " SET INTERVAL (" + expression + ")";
int no = DB.executeUpdateEx(sql, trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + sql);
}
} else {
throw new AdempiereException("PartitionConfigurationChanged");
}
}
/**
* Update partition range of table if it is not in sync with current AD_Column.RangePartitionInterval value
* @param table
* @param partitionKeyColumn
* @param trxName
* @param interval
* @param pi
*/
private void syncRange(MTable table, MColumn partitionKeyColumn, String trxName, String interval, ProcessInfo pi) {
String sql = "SELECT Column_Name FROM User_Part_Key_Columns WHERE Name=? ORDER BY Column_Position";
List<List<Object>> columnNames = DB.getSQLArrayObjectsEx(trxName, sql, table.getTableName().toUpperCase());
boolean notSync = false;
if (columnNames.size() != 1) {
notSync = true;
} else {
if (!partitionKeyColumn.getColumnName().equalsIgnoreCase(columnNames.get(0).get(0).toString()))
notSync = true;
}
if (notSync) {
StringBuilder alterStmt = new StringBuilder("ALTER TABLE ")
.append(table.getTableName())
.append(" MODIFY PARTITION BY Range ");
alterStmt.append(" (" + partitionKeyColumn.getColumnName() + ")");
alterStmt.append(" (PARTITION default_partition VALUES LESS THAN (");
alterStmt.append("MAXVALUE");
alterStmt.append("))");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
}
}
/**
* Read list or interval partition details from DB and update X_AD_TablePartition
* @param table
* @param trxName
* @param processInfo
* @param interval
*/
private void syncPartition(MTable table, String trxName, ProcessInfo processInfo, boolean interval) {
String sql =
"""
SELECT Partition_Name, High_Value
FROM User_Tab_Partitions
WHERE Table_Name=?
""";
Query query = new Query(Env.getCtx(), X_AD_TablePartition.Table_Name, "AD_Table_ID=?", trxName);
List<X_AD_TablePartition> existingList = query.setParameters(table.getAD_Table_ID()).list();
List<Integer> matchedIds = new ArrayList<Integer>();
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
try(PreparedStatement stmt = DB.prepareStatement(sql, trxName)) {
stmt.setString(1, table.getTableName().toUpperCase());
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
String partitionName = rs.getString(1);
String values = rs.getString(2);
int id = DB.getSQLValueEx(trxName, "SELECT AD_TablePartition_ID FROM AD_TablePartition WHERE AD_Table_ID=? AND Name=?", table.getAD_Table_ID(), partitionName);
if (id > 0) {
matchedIds.add(id);
} else {
String expression = interval ? "VALUES LESS THAN " + values : "VALUES " + values;
table.createTablePartition(partitionName, expression, trxName, partitionKeyColumns.get(0));
}
}
} catch (SQLException e) {
throw new DBException(e);
}
//remove X_AD_TablePartition that doesn't exists in DB
if (existingList.size() > 0) {
for (X_AD_TablePartition tablePartition : existingList) {
if (!matchedIds.contains(tablePartition.getAD_TablePartition_ID()))
tablePartition.deleteEx(true);
}
}
}
/**
* @param table
* @param trxName
* @return true if table is using automatic list partitioning
*/
private boolean isAutoList(MTable table, String trxName) {
String sql =
"""
SELECT AutoList
FROM User_Part_Tables
WHERE Table_Name = ?
""";
String autoList = DB.getSQLValueStringEx(trxName, sql, table.getTableName().toUpperCase());
return "YES".equals(autoList);
}
/**
* @param table
* @param trxName
* @return interval for partitioning
*/
private String getInterval(MTable table, String trxName) {
String sql =
"""
SELECT Interval
FROM User_Part_Tables
WHERE Table_Name = ?
""";
String interval = DB.getSQLValueStringEx(trxName, sql, table.getTableName().toUpperCase());
return interval;
}
/**
* @param table
* @param trxName
* @return true if table is partition by range in DB
*/
private boolean isRangePartitionedTable(MTable table, String trxName) {
String sql =
"""
SELECT Partitioning_Type
FROM User_Part_Tables
WHERE Table_Name = ?
""";
String type = DB.getSQLValueStringEx(trxName, sql, table.getTableName().toUpperCase());
return "RANGE".equals(type);
}
/**
* Add new list partition
* @param table
* @param partitionKeyColumn
* @param trxName
* @param pi
* @return true if new list partition added
*/
private boolean addListPartition(MTable table, MColumn partitionKeyColumn, String trxName, ProcessInfo pi) {
boolean isUpdated = false;
List<X_AD_TablePartition> partitions = new ArrayList<>();
StringBuilder sql = new StringBuilder();
sql.append("SELECT DISTINCT ").append(partitionKeyColumn.getColumnName());
sql.append(" FROM ").append(table.getTableName()).append(" PARTITION (default_partition) ");
sql.append("ORDER BY ").append(partitionKeyColumn.getColumnName());
try (PreparedStatement pstmt = DB.prepareStatement(sql.toString(), trxName))
{
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
StringBuilder name = new StringBuilder();
StringBuilder expression = new StringBuilder("VALUES (");
String s = rs.getString(partitionKeyColumn.getColumnName());
name.append(s);
if (DisplayType.isText(partitionKeyColumn.getAD_Reference_ID()))
expression.append(DB.TO_STRING(s));
else if (partitionKeyColumn.getAD_Reference_ID() == DisplayType.Date)
expression.append(DB.TO_DATE(rs.getTimestamp(partitionKeyColumn.getColumnName())));
else if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()))
expression.append(DB.TO_DATE(rs.getTimestamp(partitionKeyColumn.getColumnName()), false));
else if (DisplayType.isID(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.Integer == partitionKeyColumn.getAD_Reference_ID())
expression.append(rs.getInt(partitionKeyColumn.getColumnName()));
else if (DisplayType.isNumeric(partitionKeyColumn.getAD_Reference_ID()))
expression.append(rs.getBigDecimal(partitionKeyColumn.getColumnName()).toPlainString());
expression.append(")");
if (Character.isDigit(name.charAt(0))) {
name.insert(0, "p");
}
X_AD_TablePartition partition = table.createTablePartition(name.toString(), expression.toString(), trxName, partitionKeyColumn);
partitions.add(partition);
}
}
catch (SQLException e)
{
throw new DBException(e);
}
for(X_AD_TablePartition partition : partitions)
{
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " SPLIT PARTITION default_partition ");
alterStmt.append(partition.getExpressionPartition());
alterStmt.append(" INTO ( PARTITION ").append(partition.getName()).append(", ");
alterStmt.append("PARTITION default_partition )");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
isUpdated = true;
}
return isUpdated;
}
/**
* Add new range partition
* @param table
* @param partitionKeyColumn
* @param trxName
* @param pi
* @return true if new range partition added
*/
private boolean addRangePartition(MTable table, MColumn partitionKeyColumn, String trxName, ProcessInfo pi) {
boolean isUpdated = false;
X_AD_TablePartition partition = null;
RangePartitionColumn rangePartitionColumn = null;
String partitionKeyColumnName = partitionKeyColumn.getColumnName();
String partitionKeyColumnRangeIntervalPattern = partitionKeyColumn.getRangePartitionInterval();
StringBuilder sql = new StringBuilder();
sql.append("SELECT MIN(").append(partitionKeyColumnName).append(") AS min_value, ");
sql.append("MAX(").append(partitionKeyColumnName).append(") AS max_value ");
sql.append("FROM ").append(table.getTableName()).append(" PARTITION (default_partition) ");
List<Object> values = DB.getSQLValueObjectsEx(trxName, sql.toString());
if (values.get(0) != null && values.get(1) != null)
{
rangePartitionColumn = new RangePartitionColumn(
partitionKeyColumnName, partitionKeyColumnRangeIntervalPattern,
values.get(0), values.get(1)
);
}
if (rangePartitionColumn == null)
return false;
List<RangePartitionInterval> rangePartitionIntervals = RangePartitionInterval.createInterval(table, rangePartitionColumn, trxName);
List<String> tablePartitionNames = table.getTablePartitionNames(trxName);
for(RangePartitionInterval rangePartitionInterval : rangePartitionIntervals)
{
StringBuilder name = new StringBuilder();
name.append(rangePartitionInterval.getName());
StringBuilder countStmt = new StringBuilder("SELECT Count(*) FROM ")
.append(table.getTableName()).append(" ")
.append("WHERE ").append(" ")
.append(partitionKeyColumn.getColumnName()).append(" >= ");
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
countStmt.append("TO_DATE(").append(rangePartitionInterval.getFrom()).append(",'YYYY-MM-DD') ");
else
countStmt.append(rangePartitionInterval.getFrom()).append(" ");
countStmt.append("AND " + partitionKeyColumn.getColumnName()).append(" < ");
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
countStmt.append("TO_DATE(").append(rangePartitionInterval.getTo()).append(",'YYYY-MM-DD') ");
else
countStmt.append(rangePartitionInterval.getTo()).append(" ");
int recordCount = DB.getSQLValueEx(trxName, countStmt.toString());
if (recordCount == 0) {
if (tablePartitionNames.contains(name.toString())) {
Query query = new Query(Env.getCtx(), X_AD_TablePartition.Table_Name, "AD_Table_ID=? AND Name=?", trxName);
X_AD_TablePartition toDelete = query.setParameters(table.getAD_Table_ID(), name.toString()).first();
if (toDelete != null)
toDelete.deleteEx(true);
}
continue;
}
StringBuilder expression = new StringBuilder();
expression.append("VALUES LESS THAN (");
Object toValue = rangePartitionInterval.getTo();
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID())) {
expression.append("TO_Date(").append(toValue.toString()).append(",'YYYY-MM-DD')");
} else if (DisplayType.isNumeric(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isID(partitionKeyColumn.getAD_Reference_ID())) {
BigDecimal bd = new BigDecimal(toValue.toString());
if (DisplayType.isID(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.Integer == partitionKeyColumn.getAD_Reference_ID())
expression.append(bd.intValue());
else
expression.append(bd.toPlainString());
}
expression.append(")");
if (Character.isDigit(name.charAt(0))) {
name.insert(0, "p");
}
if (!tablePartitionNames.contains(name.toString()))
partition = table.createTablePartition(name.toString(), expression.toString(), trxName, partitionKeyColumn);
if (partition != null)
{
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " SPLIT PARTITION default_partition ");
alterStmt.append(" INTO ( PARTITION ").append(partition.getName()).append(" ").append(partition.getExpressionPartition()).append(", ");
alterStmt.append("PARTITION default_partition )");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
isUpdated = true;
}
}
return isUpdated;
}
@Override
public boolean runPostPartitionProcess(MTable table, String trxName, ProcessInfo processInfo) {
return true;
}
@Override
public String isValidConfiguration(MTable table) {
String trxName = table.get_TrxName();
if (!isPartitionedTable(table, trxName))
return null;
if (!table.isPartition())
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged") + " [" + MTable.COLUMNNAME_IsPartition + "]";
return null;
}
@Override
public String isValidConfiguration(MColumn column) {
String trxName = column.get_TrxName();
MTable table = MTable.get(Env.getCtx(), column.getAD_Table_ID(), trxName);
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(true); // re-query the partition key columns
if (column.isActive() && column.isPartitionKey()) {
if (!partitionKeyColumns.contains(column))
partitionKeyColumns.add(column);
} else {
if (partitionKeyColumns.contains(column))
partitionKeyColumns.remove(column);
}
if (partitionKeyColumns.size() > 1)
return Msg.getMsg(Env.getCtx(), "OnlyOnePartitionKeyAllowed");
//can't change partition key column for range partition
if ((!column.isPartitionKey() || !column.isActive()) && Boolean.TRUE.equals(column.get_ValueOld("IsPartitionKey"))) {
if (isRangePartitionedTable(table, trxName))
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged");
}
//can't change partition type to list for range partition
if (column.isActive() && column.isPartitionKey() && column.getPartitioningMethod().equals(MColumn.PARTITIONINGMETHOD_List)) {
if (isRangePartitionedTable(table, trxName))
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged");
}
if (column.isActive() && column.isPartitionKey() && column.getPartitioningMethod().equals(MColumn.PARTITIONINGMETHOD_Range)) {
String error = RangePartitionInterval.validateIntervalPattern(column);
if (!Util.isEmpty(error))
return error;
}
return null;
}
}

View File

@ -39,7 +39,9 @@ import java.util.logging.Level;
import javax.sql.DataSource;
import org.adempiere.db.oracle.OracleBundleActivator;
import org.adempiere.db.oracle.partition.TablePartitionService;
import org.adempiere.exceptions.DBException;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.dbPort.Convert;
import org.compiere.dbPort.Convert_Oracle;
import org.compiere.model.MColumn;
@ -1187,5 +1189,8 @@ public class DB_Oracle implements AdempiereDatabase
return "72000".equals(ex.getSQLState()) && ex.getErrorCode() == 1013;
}
@Override
public ITablePartitionService getTablePartitionService() {
return new TablePartitionService();
}
} // DB_Oracle

View File

@ -0,0 +1,650 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.adempiere.db.postgresql.partition;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;
import org.adempiere.exceptions.AdempiereException;
import org.adempiere.exceptions.DBException;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.db.partition.RangePartitionColumn;
import org.compiere.db.partition.RangePartitionInterval;
import org.compiere.model.MColumn;
import org.compiere.model.MTable;
import org.compiere.model.Query;
import org.compiere.model.X_AD_TablePartition;
import org.compiere.process.ProcessInfo;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
public class TablePartitionService implements ITablePartitionService {
public TablePartitionService() {
}
@Override
public boolean isPartitionedTable(MTable table, String trxName) {
String sql =
"""
SELECT 1 FROM pg_partitioned_table
JOIN pg_class parent ON pg_partitioned_table.partrelid = parent.oid
WHERE LOWER(relname) = LOWER(?)
""";
return DB.getSQLValueEx(trxName, sql, table.getTableName()) == 1;
}
private String getDefaultPartitionName(MTable table)
{
return table.getTableName() + "_default_partition";
}
/**
* Rename existing table to default partition
* @param table
* @param trxName
* @param processInfo
* @return true if success
*/
private boolean renameOriginalTable(MTable table, String trxName, ProcessInfo processInfo) {
StringBuilder sql = new StringBuilder();
sql.append("ALTER TABLE " + table.getTableName() + " RENAME TO " + getDefaultPartitionName(table));
int no = DB.executeUpdateEx(sql.toString(), trxName);
if (processInfo != null)
processInfo.addLog(0, null, null, no + " " + sql.toString());
return true;
}
/**
* Change primary key and unique constraint to include partition columns
* @param table
* @param trxName
* @param pi
* @return true if success
*/
private boolean migrateDBContrainsts(MTable table, String trxName, ProcessInfo pi) {
String sql =
"""
SELECT COUNT(*)
FROM pg_constraint c
WHERE conrelid = LOWER(?)::regclass
""";
int count = DB.getSQLValueEx(trxName, sql, table.getTableName());
if (count > 0)
return true;
List<String> partitionKeyColumnNames = table.getPartitionKeyColumnNames();
sql =
"""
SELECT conname AS constraint_name,
pg_get_constraintdef(c.oid) AS constraint_definition
FROM pg_constraint c
WHERE conrelid = LOWER(?)::regclass
ORDER BY conname
""";
try (PreparedStatement pstmt = DB.prepareStatement(sql, trxName))
{
pstmt.setString(1, getDefaultPartitionName(table));
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
String constraint_name = rs.getString("constraint_name");
String constraint_definition = rs.getString("constraint_definition");
if (constraint_definition.startsWith("PRIMARY KEY ") || constraint_definition.startsWith("UNIQUE "))
{
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + getDefaultPartitionName(table) + " ");
alterStmt.append("DROP CONSTRAINT " + constraint_name + " CASCADE");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
List<String> lowerCasePartitionKeyColumnNames = new ArrayList<String>();
for (String partitionKeyColumnName : partitionKeyColumnNames)
lowerCasePartitionKeyColumnNames.add(partitionKeyColumnName.toLowerCase());
String constraintColumnsStr = constraint_definition.substring(constraint_definition.indexOf("(")+1, constraint_definition.length()-1);
StringTokenizer st = new StringTokenizer(constraintColumnsStr, ",");
while (st.hasMoreTokens()) {
String token = st.nextToken().trim();
if (lowerCasePartitionKeyColumnNames.contains(token))
lowerCasePartitionKeyColumnNames.remove(token);
}
alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " ");
alterStmt.append("ADD CONSTRAINT " + constraint_name + " ");
alterStmt.append(constraint_definition.substring(0, constraint_definition.length()-1));
for (int x = 0; x < lowerCasePartitionKeyColumnNames.size(); x++)
alterStmt.append(", " + lowerCasePartitionKeyColumnNames.get(x));
alterStmt.append(")");
no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
}
}
}
catch (SQLException e)
{
throw new DBException(e);
}
try (PreparedStatement pstmt = DB.prepareStatement(sql, trxName))
{
pstmt.setString(1, getDefaultPartitionName(table));
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
String constraint_name = rs.getString("constraint_name");
String constraint_definition = rs.getString("constraint_definition");
if (constraint_definition.startsWith("CHECK ") || constraint_definition.startsWith("FOREIGN KEY "))
{
if (constraint_definition.indexOf(getDefaultPartitionName(table).toLowerCase()) >= 0) {
constraint_definition = constraint_definition.replace(getDefaultPartitionName(table).toLowerCase(), table.getTableName().toLowerCase());
}
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " ");
alterStmt.append("ADD CONSTRAINT " + constraint_name + " ");
alterStmt.append(constraint_definition);
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
}
}
}
catch (SQLException e)
{
throw new DBException(e);
}
return true;
}
/**
* Attach renamed original table as default partition
* @param table
* @param trxName
* @param pi
* @return true if success
*/
private boolean attachDefaultPartition(MTable table, String trxName, ProcessInfo pi) {
String sql =
"""
SELECT COUNT(*)
FROM pg_class base_tb
JOIN pg_inherits i ON i.inhparent = base_tb.oid
JOIN pg_class pt ON pt.oid = i.inhrelid
WHERE base_tb.oid = LOWER(?)::regclass
AND pt.relname = LOWER(?)
""";
int count = DB.getSQLValueEx(trxName, sql, table.getTableName(), getDefaultPartitionName(table));
if (count > 0)
return true;
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " ");
alterStmt.append("ATTACH PARTITION " + getDefaultPartitionName(table) + " DEFAULT");
int no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
table.createTablePartition(getDefaultPartitionName(table), "DEFAULT", trxName, table.getPartitionKeyColumns(false).get(0));
return true;
}
@Override
public boolean createPartitionedTable(MTable table, String trxName, ProcessInfo processInfo) {
if (!renameOriginalTable(table, trxName, processInfo))
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "FailedRenameOriginalTable"));
String sql =
"""
SELECT table_schema, column_name, data_type,
character_maximum_length, numeric_precision, numeric_scale,
is_nullable, column_default
FROM information_schema.columns
WHERE table_name = LOWER(?)
ORDER BY ordinal_position
""";
StringBuilder createStmt = null;
try (PreparedStatement pstmt = DB.prepareStatement(sql, trxName))
{
pstmt.setString(1, getDefaultPartitionName(table));
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
String table_schema = rs.getString("table_schema");
String column_name = rs.getString("column_name");
String data_type = rs.getString("data_type");
int character_maximum_length = rs.getInt("character_maximum_length");
int numeric_precision = rs.getInt("numeric_precision");
int numeric_scale = rs.getInt("numeric_scale");
String is_nullable = rs.getString("is_nullable");
String column_default = rs.getString("column_default");
if (createStmt == null)
{
createStmt = new StringBuilder();
createStmt.append("CREATE TABLE " + table_schema + "." + table.getTableName() + " (");
}
else
{
createStmt.append(", ");
}
createStmt.append(column_name + " " + data_type);
if (data_type.equals("numeric") && numeric_precision > 0)
createStmt.append("(" + numeric_precision + "," + numeric_scale + ")");
else if (data_type.startsWith("character") && character_maximum_length > 0)
createStmt.append("(" + character_maximum_length + ")");
if ("NO".equals(is_nullable))
createStmt.append(" NOT NULL");
if (!Util.isEmpty(column_default))
createStmt.append(" DEFAULT " + column_default);
}
if (createStmt != null)
{
createStmt.append(") PARTITION BY ");
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
MColumn partitionKeyColumn = partitionKeyColumns.get(0);
String partitioningMethod = partitionKeyColumn.getPartitioningMethod();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List))
createStmt.append("List");
else if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_Range))
createStmt.append("Range");
else
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "PartitioningMethodNotSupported", new Object[]{partitioningMethod}));
createStmt.append(" (" + partitionKeyColumn.getColumnName() + ")");
int no = DB.executeUpdateEx(createStmt.toString(), trxName);
if (processInfo != null)
processInfo.addLog(0, null, null, no + " " + createStmt.toString());
if (!migrateDBContrainsts(table, trxName, processInfo))
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "FailedMigrateDatabaseConstraints"));
if (!attachDefaultPartition(table, trxName, processInfo))
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "FailedAttachDefaultPartition"));
return true;
}
}
catch (SQLException e)
{
throw new DBException(e);
}
return false;
}
/**
* Get DB partition key definition
* @param table
* @param trxName
* @return String
*/
private String getPartitionKeyDefinition(MTable table, String trxName) {
String sql =
"""
SELECT pg_get_partkeydef(oid) AS partition_key
FROM pg_class
WHERE relkind = 'p'
AND relname = LOWER(?)
""";
return DB.getSQLValueStringEx(trxName, sql.toString(), table.getTableName());
}
/**
* Validate partition configuration
* @param table
* @param trxName
* @return String error-code - null if not error
*/
private String validateConfiguration(MTable table, String trxName) {
String currentPartitionKey = null;
String partitionKey = getPartitionKeyDefinition(table, trxName);
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
if (partitionKeyColumns.size() == 0)
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged") + ": " + partitionKey;
MColumn partitionKeyColumn = partitionKeyColumns.get(0);
String partitioningMethod = partitionKeyColumn.getPartitioningMethod();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List))
currentPartitionKey = "LIST";
else if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_Range))
currentPartitionKey = "RANGE";
currentPartitionKey += " (" + partitionKeyColumn.getColumnName().toLowerCase() + ")";
currentPartitionKey = currentPartitionKey.replaceAll(",", ", ");
if (!currentPartitionKey.equalsIgnoreCase(partitionKey))
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged") + ": " + partitionKey;
return null;
}
@Override
public boolean addPartitionAndMigrateData(MTable table, String trxName, ProcessInfo pi) {
boolean isUpdated = false;
String error = validateConfiguration(table, trxName);
if (!Util.isEmpty(error))
throw new AdempiereException(error);
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
MColumn partitionKeyColumn = partitionKeyColumns.get(0);
String partitioningMethod = partitionKeyColumn.getPartitioningMethod();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List))
{
isUpdated = addListPartition(table, partitionKeyColumn, trxName, pi);
}
else if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_Range))
{
isUpdated = addRangePartition(table, partitionKeyColumn, trxName, pi);
}
else
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), "PartitioningMethodNotSupported", new Object[]{partitioningMethod}));
return isUpdated;
}
/**
* Add new range partition
* @param table
* @param partitionKeyColumn
* @param trxName
* @param pi
* @return true if new range partition added
*/
private boolean addRangePartition(MTable table, MColumn partitionKeyColumn, String trxName, ProcessInfo pi) {
boolean isUpdated = false;
X_AD_TablePartition partition = null;
RangePartitionColumn rangePartitionColumn = null;
String partitionKeyColumnName = partitionKeyColumn.getColumnName();
String partitionKeyColumnRangeIntervalPattern = partitionKeyColumn.getRangePartitionInterval();
StringBuilder sql = new StringBuilder();
sql.append("SELECT MIN(").append(partitionKeyColumnName).append(") AS min_value, ");
sql.append("MAX(").append(partitionKeyColumnName).append(") AS max_value ");
sql.append("FROM ").append(getDefaultPartitionName(table));
List<Object> values = DB.getSQLValueObjectsEx(trxName, sql.toString());
if (values.get(0) != null && values.get(1) != null)
{
rangePartitionColumn = new RangePartitionColumn(
partitionKeyColumnName, partitionKeyColumnRangeIntervalPattern,
values.get(0), values.get(1));
}
if (rangePartitionColumn == null)
return false;
List<RangePartitionInterval> rangePartitionIntervals = RangePartitionInterval.createInterval(table, rangePartitionColumn, trxName);
List<String> tablePartitionNames = table.getTablePartitionNames(trxName);
for (RangePartitionInterval rangePartitionInterval : rangePartitionIntervals)
{
StringBuilder name = new StringBuilder();
name.append(table.getTableName().toLowerCase());
name.append("_");
name.append(rangePartitionInterval.getName());
StringBuilder expression = new StringBuilder();
expression.append("FOR VALUES FROM (");
expression.append(rangePartitionInterval.getFrom());
expression.append(") TO (");
expression.append(rangePartitionInterval.getTo());
expression.append(")");
StringBuilder countStmt = new StringBuilder("SELECT Count(*) FROM ")
.append(getDefaultPartitionName(table)).append(" ")
.append("WHERE ").append(" ")
.append(partitionKeyColumn.getColumnName()).append(" >= ");
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
countStmt.append("TO_DATE(").append(rangePartitionInterval.getFrom()).append(",'yyyy-MM-dd') ");
else
countStmt.append(rangePartitionInterval.getFrom()).append(" ");
countStmt.append("AND " + partitionKeyColumn.getColumnName()).append(" < ");
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
countStmt.append("TO_DATE(").append(rangePartitionInterval.getTo()).append(",'yyyy-MM-dd') ");
else
countStmt.append(rangePartitionInterval.getTo()).append(" ");
int recordCount = DB.getSQLValueEx(trxName, countStmt.toString());
if (recordCount == 0) {
if (tablePartitionNames.contains(name.toString())) {
Query query = new Query(Env.getCtx(), X_AD_TablePartition.Table_Name, "AD_Table_ID=? AND Name=?", trxName);
X_AD_TablePartition toDelete = query.setParameters(table.getAD_Table_ID(), name.toString()).first();
if (toDelete != null)
toDelete.deleteEx(true);
}
continue;
}
if (!tablePartitionNames.contains(name.toString()))
partition = table.createTablePartition(name.toString(), expression.toString(), trxName, partitionKeyColumn);
if (partition != null)
{
StringBuilder createStmt = new StringBuilder();
createStmt.append("CREATE TABLE " + partition.getName() + " (LIKE ");
createStmt.append(getDefaultPartitionName(table) + " INCLUDING ALL)");
int no = DB.executeUpdateEx(createStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + createStmt.toString());
StringBuilder updateStmt = new StringBuilder();
updateStmt.append("WITH x AS ( ");
updateStmt.append("DELETE FROM ").append(getDefaultPartitionName(table)).append(" ");
updateStmt.append("WHERE ").append(" ");
updateStmt.append(partitionKeyColumn.getColumnName()).append(" >= ");
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
updateStmt.append("TO_DATE(").append(rangePartitionInterval.getFrom()).append(",'yyyy-MM-dd') ");
else
updateStmt.append(rangePartitionInterval.getFrom()).append(" ");
updateStmt.append("AND " + partitionKeyColumn.getColumnName()).append(" < ");
if (DisplayType.isDate(partitionKeyColumn.getAD_Reference_ID()) || DisplayType.isTimestampWithTimeZone(partitionKeyColumn.getAD_Reference_ID()))
updateStmt.append("TO_DATE(").append(rangePartitionInterval.getTo()).append(",'yyyy-MM-dd') ");
else
updateStmt.append(rangePartitionInterval.getTo()).append(" ");
updateStmt.append("RETURNING *) ");
updateStmt.append("INSERT INTO ").append(partition.getName()).append(" ");
updateStmt.append("SELECT * FROM x");
no = DB.executeUpdateEx(updateStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + updateStmt.toString());
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " ");
alterStmt.append("ATTACH PARTITION " + partition.getName() + " " + partition.getExpressionPartition());
no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
isUpdated = true;
}
}
return isUpdated;
}
/**
* Add new list partition
* @param table
* @param partitionKeyColumn
* @param trxName
* @param pi
* @return true if new list partition added
*/
private boolean addListPartition(MTable table, MColumn partitionKeyColumn, String trxName, ProcessInfo pi) {
boolean isUpdated = false;
List<X_AD_TablePartition> partitions = new ArrayList<X_AD_TablePartition>();
String nameColumn = "'" + table.getTableName().toLowerCase() + "_' || " + partitionKeyColumn.getColumnName();
String expressionColumn = "'FOR VALUES IN (''' || " + partitionKeyColumn.getColumnName() + " || ''')'";
StringBuilder sql = new StringBuilder();
sql.append("SELECT DISTINCT ").append(nameColumn).append(" AS name, ");
sql.append(expressionColumn).append(" AS expression, ");
sql.append(partitionKeyColumn.getColumnName()).append(" ");
sql.append("FROM ").append(getDefaultPartitionName(table)).append(" ");
HashMap<String, Object> columnValues = new HashMap<>();
try (PreparedStatement pstmt = DB.prepareStatement(sql.toString(), trxName))
{
ResultSet rs = pstmt.executeQuery();
while (rs.next())
{
String name = rs.getString("name");
String expression = rs.getString("expression");
Object value = new ArrayList<Object>();
value = rs.getObject(partitionKeyColumn.getColumnName());
columnValues.put(name, value);
X_AD_TablePartition partition = table.createTablePartition(name, expression, trxName, partitionKeyColumn);
partitions.add(partition);
}
}
catch (SQLException e)
{
throw new DBException(e);
}
for (X_AD_TablePartition partition : partitions)
{
Object value = columnValues.get(partition.getName());
StringBuilder createStmt = new StringBuilder();
createStmt.append("CREATE TABLE " + partition.getName() + " (LIKE ");
createStmt.append(getDefaultPartitionName(table) + " INCLUDING ALL)");
int no = DB.executeUpdateEx(createStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + createStmt.toString());
StringBuilder updateStmt = new StringBuilder();
updateStmt.append("WITH x AS ( ");
updateStmt.append("DELETE FROM ").append(getDefaultPartitionName(table)).append(" ");
updateStmt.append("WHERE ").append(" ");
updateStmt.append(partitionKeyColumn.getColumnName()).append("=");
if (DisplayType.isText(partitionKeyColumn.getAD_Reference_ID()))
updateStmt.append("'").append(value).append("' ");
else
updateStmt.append(value).append(" ");
updateStmt.append("RETURNING *) ");
updateStmt.append("INSERT INTO ").append(partition.getName()).append(" ");
updateStmt.append("SELECT * FROM x");
no = DB.executeUpdateEx(updateStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + updateStmt.toString());
StringBuilder alterStmt = new StringBuilder();
alterStmt.append("ALTER TABLE " + table.getTableName() + " ");
alterStmt.append("ATTACH PARTITION " + partition.getName() + " " + partition.getExpressionPartition());
no = DB.executeUpdateEx(alterStmt.toString(), trxName);
if (pi != null)
pi.addLog(0, null, null, no + " " + alterStmt.toString());
isUpdated = true;
}
return isUpdated;
}
@Override
public boolean runPostPartitionProcess(MTable table, String trxName, ProcessInfo processInfo) {
StringBuilder stmt = new StringBuilder();
stmt.append("VACUUM ANALYZE " + table.getTableName());
int no = DB.executeUpdateEx(stmt.toString(), trxName);
if (processInfo != null)
processInfo.addLog(0, null, null, no + " " + stmt.toString());
return true;
}
@Override
public String isValidConfiguration(MTable table) {
String trxName = table.get_TrxName();
if (!isPartitionedTable(table, trxName))
return null;
if (!table.isPartition())
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged") + " [" + MTable.COLUMNNAME_IsPartition + "]";
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(false);
MColumn partitionKeyColumn = partitionKeyColumns.get(0);
String currentPartitionKey = null;
String partitioningMethod = partitionKeyColumn.getPartitioningMethod();
if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_List))
currentPartitionKey = "LIST";
else if (partitioningMethod.equals(MColumn.PARTITIONINGMETHOD_Range))
currentPartitionKey = "RANGE";
String partitionKey = getPartitionKeyDefinition(table, trxName);
if (!partitionKey.toLowerCase().startsWith(currentPartitionKey.toLowerCase()))
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged") + " [" + MColumn.COLUMNNAME_PartitioningMethod + "]";
return null;
}
@Override
public String isValidConfiguration(MColumn column) {
String trxName = column.get_TrxName();
MTable table = MTable.get(Env.getCtx(), column.getAD_Table_ID(), trxName);
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(true); // re-query the partition key columns
if (column.isActive() && column.isPartitionKey()) {
if (!partitionKeyColumns.contains(column))
partitionKeyColumns.add(column);
} else {
if (partitionKeyColumns.contains(column))
partitionKeyColumns.remove(column);
}
if (partitionKeyColumns.size() > 1)
return Msg.getMsg(Env.getCtx(), "OnlyOnePartitionKeyAllowed");
if (column.isActive() && column.isPartitionKey() && column.getPartitioningMethod().equals(MColumn.PARTITIONINGMETHOD_Range)) {
String error = RangePartitionInterval.validateIntervalPattern(column);
if (!Util.isEmpty(error))
return error;
}
if (!isPartitionedTable(table, trxName))
return null;
if (column.is_ValueChanged(MColumn.COLUMNNAME_IsPartitionKey)
|| (column.isPartitionKey() && column.is_ValueChanged(MColumn.COLUMNNAME_IsActive))
|| (column.isPartitionKey() && column.is_ValueChanged(MColumn.COLUMNNAME_SeqNoPartition))) {
return validateConfiguration(table, trxName);
}
if (column.isPartitionKey() && column.is_ValueChanged(MColumn.COLUMNNAME_RangePartitionInterval))
return Msg.getMsg(Env.getCtx(), "PartitionConfigurationChanged") + " [" + MColumn.COLUMNNAME_RangePartitionInterval + "]";
return null;
}
}

View File

@ -45,7 +45,9 @@ import javax.sql.DataSource;
import javax.sql.RowSet;
import org.adempiere.db.postgresql.PostgreSQLBundleActivator;
import org.adempiere.db.postgresql.partition.TablePartitionService;
import org.adempiere.exceptions.DBException;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.dbPort.Convert;
import org.compiere.dbPort.Convert_PostgreSQL;
import org.compiere.model.MColumn;
@ -1371,5 +1373,8 @@ public class DB_PostgreSQL implements AdempiereDatabase
return "57014".equals(ex.getSQLState());
}
@Override
public ITablePartitionService getTablePartitionService() {
return new TablePartitionService();
}
} // DB_PostgreSQL

View File

@ -52,4 +52,11 @@
version="0.0.0"
unpack="false"/>
<plugin
id="org.idempiere.tablepartition"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
</feature>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.idempiere.tablepartition</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ds.core.builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,3 @@
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false

View File

@ -0,0 +1,15 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Table Partition
Bundle-SymbolicName: org.idempiere.tablepartition;singleton:=true
Bundle-Version: 11.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=17))"
Export-Package: org.idempiere.tablepartition.process
Require-Bundle: org.adempiere.base;bundle-version="0.0.0"
Bundle-ClassPath: .
Automatic-Module-Name: org.idempiere.tablepartition
Bundle-Vendor: iDempiere Community
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/org.idempiere.tablepartition.ProcessFactoryImpl.xml,
OSGI-INF/org.idempiere.tablepartition.callout.ColumnCalloutFactoryImpl.xml

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.idempiere.tablepartition.ProcessFactoryImpl">
<property name="service.ranking" type="Integer" value="1"/>
<service>
<provide interface="org.adempiere.base.IProcessFactory"/>
</service>
<implementation class="org.idempiere.tablepartition.ProcessFactoryImpl"/>
</scr:component>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" immediate="true" name="org.idempiere.tablepartition.callout.ColumnCalloutFactoryImpl">
<service>
<provide interface="org.adempiere.base.IColumnCalloutFactory"/>
</service>
<implementation class="org.idempiere.tablepartition.callout.ColumnCalloutFactoryImpl"/>
</scr:component>

View File

@ -0,0 +1,5 @@
bin.includes = META-INF/,\
.,\
OSGI-INF/
source.. = src/
jre.compilation.profile = JavaSE-17

View File

@ -0,0 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.idempiere</groupId>
<artifactId>org.idempiere.parent</artifactId>
<version>${revision}</version>
<relativePath>../org.idempiere.parent/pom.xml</relativePath>
</parent>
<artifactId>org.idempiere.tablepartition</artifactId>
<packaging>eclipse-plugin</packaging>
</project>

View File

@ -0,0 +1,42 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.idempiere.tablepartition;
import org.adempiere.base.AnnotationBasedProcessFactory;
import org.adempiere.base.IProcessFactory;
import org.osgi.service.component.annotations.Component;
@Component(immediate = true, service = IProcessFactory.class, property = {"service.ranking:Integer=1"})
public class ProcessFactoryImpl extends AnnotationBasedProcessFactory {
/**
* Default constructor
*/
public ProcessFactoryImpl() {
}
@Override
protected String[] getPackages() {
return new String[] {"org.idempiere.tablepartition.process"};
}
}

View File

@ -0,0 +1,153 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Elaine Tan - etantg *
**********************************************************************/
package org.idempiere.tablepartition;
import java.util.List;
import java.util.logging.Level;
import org.adempiere.exceptions.AdempiereException;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.model.MColumn;
import org.compiere.model.MTable;
import org.compiere.process.ProcessInfo;
import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
/**
* Create/update table partition task
*/
public class TablePartitionTask {
private MTable table;
private ProcessInfo pi;
private Trx trx;
private ITablePartitionService partitionService;
private CLogger log = CLogger.getCLogger (getClass());
/**
* @param table
* @param pi
* @param partitionService
*/
public TablePartitionTask(MTable table, ProcessInfo pi, ITablePartitionService partitionService)
{
this.table = table;
this.pi = pi;
this.partitionService = partitionService;
}
/**
* Execute create/update table partition task
* @return true if success
*/
public boolean executeTask()
{
boolean isError = false;
boolean isUpdated = false;
String trxName = Trx.createTrxName("TablePartition-");
trx = Trx.get(trxName, true);
trx.setDisplayName(getClass().getName()+"_runProcess");
try
{
addLog(Msg.getElement(Env.getCtx(), "TableName") + ": " + table.getTableName());
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(true);
if (partitionKeyColumns.isEmpty())
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "PartitionKeyRequired"));
if (!isPartitionedTable())
{
if (!createPartitionedTable())
throw new AdempiereException(Msg.getMsg(Env.getCtx(), "FailedCreatePartitionedTable"));
}
isUpdated = addPartitionAndMigrateData();
trx.commit();
}
catch (Exception e)
{
log.log(Level.SEVERE, e.getMessage(), e);
isError = true;
addLog(Msg.getMsg(Env.getCtx(), "Error") + e.getLocalizedMessage());
trx.rollback();
}
finally
{
trx.close();
trx = null;
}
if (!isError && isUpdated && !runPostPartitionProcess())
{
isError = true;
addLog(Msg.getMsg(Env.getCtx(), "FailedRunPostMigrationData"));
}
if (isUpdated)
table.getTablePartitions(true, trxName);
return !isError;
}
/**
* Add process log
* @param msg
*/
private void addLog(String msg)
{
if (pi != null && msg != null)
pi.addLog(0, null, null, msg);
}
/**
* @return transaction name
*/
private String getTrxName()
{
if (trx != null)
return trx.getTrxName();
return null;
}
private boolean isPartitionedTable() {
return partitionService.isPartitionedTable(table, getTrxName());
}
private boolean createPartitionedTable() {
return partitionService.createPartitionedTable(table, getTrxName(), pi);
}
private boolean addPartitionAndMigrateData() {
return partitionService.addPartitionAndMigrateData(table, getTrxName(), pi);
}
private boolean runPostPartitionProcess() {
return partitionService.runPostPartitionProcess(table, getTrxName(), pi);
}
}

View File

@ -0,0 +1,67 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.idempiere.tablepartition.callout;
import java.util.Properties;
import org.adempiere.base.IColumnCallout;
import org.adempiere.base.annotation.Callout;
import org.compiere.db.partition.RangePartitionInterval;
import org.compiere.model.GridField;
import org.compiere.model.GridTab;
import org.compiere.model.MColumn;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Util;
@Callout(tableName = "AD_Column", columnName = {"IsPartitionKey", "RangePartitionInterval"})
public class ColumnCallout implements IColumnCallout {
public ColumnCallout() {
}
@Override
public String start(Properties ctx, int WindowNo, GridTab mTab, GridField mField, Object value, Object oldValue) {
if ("IsPartitionKey".equals(mField.getColumnName())) {
if (Boolean.TRUE.equals(value)) {
Object seqNo = mTab.getValue("SeqNoPartition");
if (seqNo == null || ((Number)seqNo).intValue() == 0) {
String sql = "SELECT COALESCE(MAX(SeqNoPartition),0)+10 AS DefaultValue FROM AD_Column WHERE AD_Table_ID=? AND IsActive='Y' AND IsPartitionKey='Y'";
int ii = DB.getSQLValue(null, sql, mTab.getValue("AD_Table_ID"));
mTab.setValue("SeqNoPartition", ii);
}
} else {
Object seqNo = mTab.getValue("SeqNoPartition");
if (seqNo != null)
mTab.setValue("SeqNoPartition", null);
}
} else if ("RangePartitionInterval".equals(mField.getColumnName())) {
MColumn column = MColumn.getCopy(Env.getCtx(), mTab.getRecord_ID(), null);
column.setRangePartitionInterval(value.toString());
String error = RangePartitionInterval.validateIntervalPattern(column);
if (!Util.isEmpty(error, true))
return error;
}
return null;
}
}

View File

@ -0,0 +1,39 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
**********************************************************************/
package org.idempiere.tablepartition.callout;
import org.adempiere.base.AnnotationBasedColumnCalloutFactory;
import org.adempiere.base.IColumnCalloutFactory;
import org.osgi.service.component.annotations.Component;
@Component(immediate = true, service = IColumnCalloutFactory.class)
public class ColumnCalloutFactoryImpl extends AnnotationBasedColumnCalloutFactory {
public ColumnCalloutFactoryImpl() {
}
@Override
protected String[] getPackages() {
return new String[] {"org.idempiere.tablepartition.callout"};
}
}

View File

@ -0,0 +1,115 @@
/***********************************************************************
* This file is part of iDempiere ERP Open Source *
* http://www.idempiere.org *
* *
* Copyright (C) Contributors *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301, USA. *
* *
* Contributors: *
* - Elaine Tan - etantg *
**********************************************************************/
package org.idempiere.tablepartition.process;
import java.util.List;
import org.compiere.db.partition.ITablePartitionService;
import org.compiere.model.MColumn;
import org.compiere.model.MProcessPara;
import org.compiere.model.MTable;
import org.compiere.model.Query;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.process.SvrProcess;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.idempiere.tablepartition.TablePartitionTask;
@org.adempiere.base.annotation.Process
public class CreatePartition extends SvrProcess {
private int p_record_ID = 0;
private String p_partitioningMethod = null;
private String p_tableName = null;
@Override
protected void prepare() {
ProcessInfoParameter[] para = getParameter();
for (int i = 0; i < para.length; i++)
{
String name = para[i].getParameterName();
if (para[i].getParameter() == null)
;
else if (name.equals("PartitioningMethod"))
p_partitioningMethod = para[i].getParameterAsString();
else if (name.equals("TableName"))
p_tableName = para[i].getParameterAsString();
else
MProcessPara.validateUnknownParameter(getProcessInfo().getAD_Process_ID(), para[i]);
}
p_record_ID = getRecord_ID();
}
@Override
protected String doIt() throws Exception {
ITablePartitionService service = DB.getDatabase().getTablePartitionService();
if (service == null) {
return "@Error@ " + Msg.getMsg(getCtx(), "DBAdapterNoTablePartitionSupport");
}
int successCount = 0;
int errorCount = 0;
if (p_record_ID > 0)
{
MTable table = new MTable(Env.getCtx(), p_record_ID, null);
TablePartitionTask tp = new TablePartitionTask(table, getProcessInfo(), service);
boolean success = tp.executeTask();
if (success)
++successCount;
else
++errorCount;
}
else
{
String whereClause = MTable.COLUMNNAME_IsPartition + "='Y' AND " + MTable.COLUMNNAME_IsView + "='N'";
if (p_tableName != null)
whereClause += " AND " + MTable.COLUMNNAME_TableName + " LIKE '" + p_tableName + "'";
List<MTable> tables = new Query(getCtx(), MTable.Table_Name, whereClause, null)
.setOnlyActiveRecords(true)
.setOrderBy(MTable.COLUMNNAME_TableName)
.list();
for (MTable table : tables)
{
List<MColumn> partitionKeyColumns = table.getPartitionKeyColumns(true);
if (partitionKeyColumns.isEmpty())
continue;
if (p_partitioningMethod != null)
{
if (!p_partitioningMethod.equals(partitionKeyColumns.get(0).getPartitioningMethod()))
continue;
}
TablePartitionTask tp = new TablePartitionTask(table, getProcessInfo(), service);
boolean success = tp.executeTask();
if (success)
++successCount;
else
++errorCount;
}
}
return Msg.getMsg(Env.getCtx(), "Updated") + ": " + successCount + ", " + Msg.getMsg(Env.getCtx(), "Error") + errorCount;
}
}

View File

@ -420,9 +420,10 @@
<setEntry value="org.compiere.db.oracle.provider@default:default"/>
<setEntry value="org.compiere.db.postgresql.provider@default:default"/>
<setEntry value="org.idempiere.hazelcast.service@default:default"/>
<setEntry value="org.idempiere.tablepartition@default:default"/>
<setEntry value="org.idempiere.test@default:default"/>
<setEntry value="org.idempiere.webservices@default:default"/>
<setEntry value="org.idempiere.webservices.resources@default:default"/>
<setEntry value="org.idempiere.webservices@default:default"/>
<setEntry value="org.idempiere.zk.billboard.chart@default:default"/>
<setEntry value="org.idempiere.zk.billboard@default:default"/>
<setEntry value="org.idempiere.zk.extra@default:default"/>

View File

@ -116,6 +116,11 @@
<id>org.idempiere.hazelcast.service</id>
<versionRange>0.0.0</versionRange>
</requirement>
<requirement>
<type>eclipse-plugin</type>
<id>org.idempiere.tablepartition</id>
<versionRange>0.0.0</versionRange>
</requirement>
</extraRequirements>
</dependency-resolution>
</configuration>

View File

@ -58,11 +58,12 @@
<module>org.idempiere.webservices.client-feature</module>
<module>org.idempiere.jetty.osgi.boot.fragment</module>
<module>org.idempiere.ui.sso.oidc</module>
<module>org.idempiere.tablepartition</module>
<module>org.idempiere.p2</module>
<module>org.idempiere.javadoc</module>
<module>org.idempiere.test-feature</module>
<module>org.idempiere.test</module>
<module>org.idempiere.p2.targetplatform</module>
<module>org.idempiere.p2.targetplatform</module>
</modules>
</project>