You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by al...@apache.org on 2022/02/22 17:03:17 UTC

[fineract] branch develop updated: FINERACT-984-6: PostgreSQL support

This is an automated email from the ASF dual-hosted git repository.

aleks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 8389106  FINERACT-984-6: PostgreSQL support
8389106 is described below

commit 8389106a58df6f3b1f16bb2795ffee49b3e6ec61
Author: Arnold Galovics <ga...@gmail.com>
AuthorDate: Tue Feb 22 17:16:56 2022 +0100

    FINERACT-984-6: PostgreSQL support
---
 ...er-compose.yml => docker-compose-postgresql.yml |   38 +-
 docker-compose.yml                                 |    2 +-
 fineract-db/docker/postgresql/01-init.sh           |   29 +
 fineract-provider/build.gradle                     |    3 +
 .../JournalEntryReadPlatformServiceImpl.java       |   42 +-
 ...ournalEntryRunningBalanceUpdateServiceImpl.java |   50 +-
 ...ProvisioningEntriesReadPlatformServiceImpl.java |   36 +-
 .../apache/fineract/adhocquery/domain/AdHoc.java   |    2 +-
 .../service/AdHocReadPlatformServiceImpl.java      |   18 +-
 .../service/AuditReadPlatformServiceImpl.java      |   14 +-
 .../campaigns/email/domain/EmailCampaign.java      |    2 +-
 .../EmailCampaignReadPlatformServiceImpl.java      |    2 +-
 .../service/EmailReadPlatformServiceImpl.java      |   26 +-
 .../SmsCampaignReadPlatformServiceImpl.java        |   30 +-
 .../core/config/PersistenceConfig.java             |    5 +-
 .../core/service/PaginationHelper.java             |   30 +-
 .../database/DatabaseIndependentQueryService.java  |   10 +-
 .../service/database/DatabaseQueryService.java     |    6 +-
 .../database/DatabaseSpecificSQLGenerator.java     |  150 ++
 .../core/service/database/DatabaseType.java        |    2 +-
 .../service/database/DatabaseTypeResolver.java     |   56 +-
 .../core/service/database/MySQLQueryService.java   |   28 +-
 .../service/database/PostgreSQLQueryService.java   |   65 +
 .../DatabaseAwareMigrationContextProvider.java     |    7 +-
 .../migration/ExtendedSpringLiquibaseFactory.java  |    2 +-
 .../data/CreditReportReadPlatformServiceImpl.java  |    2 +-
 .../creditbureau/domain/CreditBureau.java          |    2 +
 .../domain/CreditBureauLoanProductMapping.java     |    7 +-
 .../creditbureau/domain/CreditBureauToken.java     |    6 +-
 .../creditbureau/domain/CreditReport.java          |    6 +-
 .../domain/OrganisationCreditBureau.java           |    2 +
 ...uLoanProductMappingReadPlatformServiceImpl.java |    2 +-
 .../CreditBureauReadPlatformServiceImpl.java       |    2 +-
 ...isationCreditBureauReadPlatformServiceImpl.java |    2 +-
 .../data/ResultsetColumnHeaderData.java            |    9 +-
 ...tityDatatableChecksReadPlatformServiceImpl.java |   22 +-
 .../service/GenericDataServiceImpl.java            |   41 +-
 .../service/ReadWriteNonCoreDataServiceImpl.java   |  212 ++-
 .../service/SchedulerJobRunnerReadServiceImpl.java |   55 +-
 .../openjpa/OpenJpaTransactionManager.java         |   42 +
 .../ReportMailingJobReadPlatformServiceImpl.java   |   21 +-
 ...ailingJobRunHistoryReadPlatformServiceImpl.java |   22 +-
 .../sms/service/SmsReadPlatformServiceImpl.java    |   37 +-
 .../interoperation/service/InteropServiceImpl.java |   15 +-
 .../NotificationReadPlatformServiceImpl.java       |   27 +-
 .../service/TopicDomainServiceImpl.java            |    2 +
 .../service/OfficeReadPlatformServiceImpl.java     |   16 +-
 .../TellerManagementReadPlatformServiceImpl.java   |   18 +-
 .../AccountTransfersReadPlatformServiceImpl.java   |   28 +-
 .../PortfolioAccountReadPlatformServiceImpl.java   |    9 +-
 ...gInstructionHistoryReadPlatformServiceImpl.java |   20 +-
 ...StandingInstructionReadPlatformServiceImpl.java |   31 +-
 ...tandingInstructionWritePlatformServiceImpl.java |    9 +-
 .../client/domain/ClientFamilyMembers.java         |    4 +-
 .../ClientChargeReadPlatformServiceImpl.java       |   20 +-
 .../service/ClientReadPlatformServiceImpl.java     |   25 +-
 .../ClientTransactionReadPlatformServiceImpl.java  |   24 +-
 .../CollectionSheetReadPlatformServiceImpl.java    |   55 +-
 .../service/CenterReadPlatformServiceImpl.java     |   26 +-
 .../service/GroupReadPlatformServiceImpl.java      |   14 +-
 .../InterestRateChartReadPlatformServiceImpl.java  |   24 +-
 ...terestRateChartSlabReadPlatformServiceImpl.java |   17 +-
 .../portfolio/loanaccount/domain/Loan.java         |   10 +-
 ...LoanScheduleCalculationPlatformServiceImpl.java |    3 +
 ...LoanScheduleHistoryReadPlatformServiceImpl.java |    2 +
 ...oanScheduleHistoryWritePlatformServiceImpl.java |    2 +
 .../LoanScheduleWritePlatformServiceImpl.java      |    2 +
 .../LoanAccrualWritePlatformServiceImpl.java       |    8 +-
 .../service/LoanArrearsAgingServiceImpl.java       |   24 +-
 .../service/LoanReadPlatformServiceImpl.java       |  154 +-
 .../LoanProductReadPlatformServiceImpl.java        |   24 +-
 ...WithPostDatedChecksReadPlatformServiceImpl.java |    2 +
 ...ntInterestRateChartReadPlatformServiceImpl.java |   12 +-
 ...ntOnHoldTransactionReadPlatformServiceImpl.java |   23 +-
 .../DepositAccountReadPlatformServiceImpl.java     |   44 +-
 .../SavingsAccountReadPlatformServiceImpl.java     |   61 +-
 .../service/SavingsSchedularInterestPoster.java    |    4 +
 .../service/SavingsSchedularServiceImpl.java       |    1 +
 ...hareAccountDividendReadPlatformServiceImpl.java |   21 +-
 .../ShareAccountReadPlatformServiceImpl.java       |   20 +-
 ...hareProductDividendReadPlatformServiceImpl.java |   21 +-
 .../ShareProductReadPlatformServiceImpl.java       |   15 +-
 .../service/ScheduledJobRunnerServiceImpl.java     |   10 +-
 ...ordValidationPolicyReadPlatformServiceImpl.java |   17 +-
 .../service/PermissionReadPlatformServiceImpl.java |   21 +-
 .../resources/db/changelog/db.changelog-master.xml |    1 +
 .../tenant-store/changelog-tenant-store.xml        |    3 +-
 .../0003_reset_postgresql_sequences.xml}           |    9 +-
 .../db/changelog/tenant/changelog-tenant.xml       |    4 +-
 .../0003_postgresql_specific_initial_data.xml      | 1972 ++++++++++++++++++++
 .../parts/0004_camelcase_column_renaming.xml       |   38 +
 ...TestsWithoutDatabaseAndNoJobsConfiguration.java |    9 +
 92 files changed, 3394 insertions(+), 674 deletions(-)

diff --git a/docker-compose.yml b/docker-compose-postgresql.yml
similarity index 77%
copy from docker-compose.yml
copy to docker-compose-postgresql.yml
index c38e670..1c9a41f5 100644
--- a/docker-compose.yml
+++ b/docker-compose-postgresql.yml
@@ -21,20 +21,24 @@
 version: '3.7'
 services:
   # Backend service
-  fineractmysql:
-    image: mariadb:10.6
+  fineractpostgresql:
+    image: postgres:13.4
     volumes:
-      - ./fineract-db/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf
-      - ./fineract-db/docker:/docker-entrypoint-initdb.d:Z,ro
+      - ./fineract-db/docker/postgresql:/docker-entrypoint-initdb.d/:Z,ro
     restart: always
     environment:
-      MYSQL_ROOT_PASSWORD: skdcnwauicn2ucnaecasdsajdnizucawencascdca
+      POSTGRES_USER: root
+      POSTGRES_PASSWORD: skdcnwauicn2ucnaecasdsajdnizucawencascdca
+      FINERACT_DB_USER: postgres
+      FINERACT_DB_PASS: skdcnwauicn2ucnaecasdsajdnizucawencascdca
+      FINERACT_TENANTS_DB_NAME: fineract_tenants
+      FINERACT_TENANT_DEFAULT_DB_NAME: fineract_default
     healthcheck:
-      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "--password=skdcnwauicn2ucnaecasdsajdnizucawencascdca" ]
+      test: [ "CMD", "pg_isready", "-q", "-d", "postgres", "-U", "root" ]
       timeout: 10s
       retries: 10
     ports:
-      - "3306:3306"
+      - "5432:5432"
   fineract-server:
     image: fineract:latest
     volumes:
@@ -46,20 +50,20 @@ services:
     ports:
       - 8443:8443
     depends_on:
-      fineractmysql:
+      fineractpostgresql:
         condition: service_healthy
     environment:
       # TODO: env vars prefixed with "fineract_tenants_*" will be removed with one of the next releases
-      #- fineract_tenants_driver=org.mariadb.jdbc.Driver
-      #- fineract_tenants_url=jdbc:mariadb://fineractmysql:3306/fineract_tenants
-      #- fineract_tenants_uid=root
+      #- fineract_tenants_driver=org.postgresql.Driver
+      #- fineract_tenants_url=jdbc:postgresql://fineractpostgresql:5432/fineract_tenants
+      #- fineract_tenants_uid=postgres
       #- fineract_tenants_pwd=skdcnwauicn2ucnaecasdsajdnizucawencascdca
       # NOTE: node aware scheduler
       - FINERACT_NODE_ID=1
       # NOTE: env vars prefixed "FINERACT_HIKARI_*" are used to configure the database connection pool
-      - FINERACT_HIKARI_DRIVER_CLASS_NAME=org.mariadb.jdbc.Driver
-      - FINERACT_HIKARI_JDBC_URL=jdbc:mariadb://fineractmysql:3306/fineract_tenants
-      - FINERACT_HIKARI_USERNAME=root
+      - FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME=org.postgresql.Driver
+      - FINERACT_HIKARI_JDBC_URL=jdbc:postgresql://fineractpostgresql:5432/fineract_tenants
+      - FINERACT_HIKARI_USERNAME=postgres
       - FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
       # ... following variables are optional; "application.properties" contains reasonable defaults (same as here)
       - FINERACT_HIKARI_MINIMUM_IDLE=3
@@ -81,9 +85,9 @@ services:
       - FINERACT_HIKARI_DS_PROPERTIES_LOG_SLOW_QUERIES=true
       - FINERACT_HIKARI_DS_PROPERTIES_DUMP_QUERIES_IN_EXCEPTION=true
       # NOTE: env vars prefixed "FINERACT_DEFAULT_TENANTDB_*" are used to create the default tenant database
-      - FINERACT_DEFAULT_TENANTDB_HOSTNAME=fineractmysql
-      - FINERACT_DEFAULT_TENANTDB_PORT=3306
-      - FINERACT_DEFAULT_TENANTDB_UID=root
+      - FINERACT_DEFAULT_TENANTDB_HOSTNAME=fineractpostgresql
+      - FINERACT_DEFAULT_TENANTDB_PORT=5432
+      - FINERACT_DEFAULT_TENANTDB_UID=postgres
       - FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
       - FINERACT_DEFAULT_TENANTDB_CONN_PARAMS=
       - FINERACT_DEFAULT_TENANTDB_TIMEZONE=Asia/Kolkata
diff --git a/docker-compose.yml b/docker-compose.yml
index c38e670..1a3ba7c 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -57,7 +57,7 @@ services:
       # NOTE: node aware scheduler
       - FINERACT_NODE_ID=1
       # NOTE: env vars prefixed "FINERACT_HIKARI_*" are used to configure the database connection pool
-      - FINERACT_HIKARI_DRIVER_CLASS_NAME=org.mariadb.jdbc.Driver
+      - FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME=org.mariadb.jdbc.Driver
       - FINERACT_HIKARI_JDBC_URL=jdbc:mariadb://fineractmysql:3306/fineract_tenants
       - FINERACT_HIKARI_USERNAME=root
       - FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca
diff --git a/fineract-db/docker/postgresql/01-init.sh b/fineract-db/docker/postgresql/01-init.sh
new file mode 100644
index 0000000..7a8fd49
--- /dev/null
+++ b/fineract-db/docker/postgresql/01-init.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+set -e
+export PGPASSWORD=$POSTGRES_PASSWORD;
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
+  CREATE USER $FINERACT_DB_USER WITH PASSWORD '$FINERACT_DB_PASS';
+  CREATE DATABASE $FINERACT_TENANTS_DB_NAME;
+  CREATE DATABASE $FINERACT_TENANT_DEFAULT_DB_NAME;
+  GRANT ALL PRIVILEGES ON DATABASE $FINERACT_TENANTS_DB_NAME TO $FINERACT_DB_USER;
+  GRANT ALL PRIVILEGES ON DATABASE $FINERACT_TENANT_DEFAULT_DB_NAME TO $FINERACT_DB_USER;
+EOSQL
\ No newline at end of file
diff --git a/fineract-provider/build.gradle b/fineract-provider/build.gradle
index 56bf75b..960de21 100644
--- a/fineract-provider/build.gradle
+++ b/fineract-provider/build.gradle
@@ -200,6 +200,7 @@ configurations {
 }
 dependencies {
     driver 'org.mariadb.jdbc:mariadb-java-client:2.7.4'
+    driver 'org.postgresql:postgresql:42.1.4'
 }
 
 URLClassLoader loader = GroovyObject.class.classLoader
@@ -237,6 +238,7 @@ bootRun {
 
     dependencies {
         implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.4'
+        implementation 'org.postgresql:postgresql:42.1.4'
     }
 
     classpath += files("build/generated/swagger-ui")
@@ -316,6 +318,7 @@ jib {
 
     dependencies {
         implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.4'
+        implementation 'org.postgresql:postgresql:42.1.4'
     }
 
     extraDirectories {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
index 6547e88..a72e74c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryReadPlatformServiceImpl.java
@@ -49,6 +49,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.office.data.OfficeData;
@@ -77,18 +78,22 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
     private final ColumnValidator columnValidator;
     private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper;
 
-    private final PaginationHelper<JournalEntryData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public JournalEntryReadPlatformServiceImpl(final RoutingDataSource dataSource,
             final GLAccountReadPlatformService glAccountReadPlatformService, final ColumnValidator columnValidator,
             final OfficeReadPlatformService officeReadPlatformService,
-            final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper) {
+            final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.glAccountReadPlatformService = glAccountReadPlatformService;
         this.officeReadPlatformService = officeReadPlatformService;
         this.financialActivityAccountRepositoryWrapper = financialActivityAccountRepositoryWrapper;
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     private static final class GLJournalEntryMapper implements RowMapper<JournalEntryData> {
@@ -250,7 +255,7 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
 
         GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(rm.schema());
 
         final Object[] objectArray = new Object[15];
@@ -304,28 +309,19 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
             String fromDateString = null;
             String toDateString = null;
             if (fromDate != null && toDate != null) {
-                sqlBuilder.append(whereClose + " journalEntry.entry_date between ? and ? ");
-
-                whereClose = " and ";
-
                 fromDateString = df.format(fromDate);
                 toDateString = df.format(toDate);
-                objectArray[arrayPos] = fromDateString;
-                arrayPos = arrayPos + 1;
-                objectArray[arrayPos] = toDateString;
-                arrayPos = arrayPos + 1;
+                sqlBuilder.append(whereClose + " journalEntry.entry_date between '" + fromDateString + "' and '" + toDateString + "' ");
+
+                whereClose = " and ";
             } else if (fromDate != null) {
-                sqlBuilder.append(whereClose + " journalEntry.entry_date >= ? ");
                 fromDateString = df.format(fromDate);
-                objectArray[arrayPos] = fromDateString;
-                arrayPos = arrayPos + 1;
+                sqlBuilder.append(whereClose + " journalEntry.entry_date >= '" + fromDateString + "' ");
                 whereClose = " and ";
 
             } else if (toDate != null) {
-                sqlBuilder.append(whereClose + " journalEntry.entry_date <= ? ");
                 toDateString = df.format(toDate);
-                objectArray[arrayPos] = toDateString;
-                arrayPos = arrayPos + 1;
+                sqlBuilder.append(whereClose + " journalEntry.entry_date <= '" + toDateString + "' ");
 
                 whereClose = " and ";
             }
@@ -368,15 +364,16 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
         final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray, rm);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, rm);
     }
 
     @Override
@@ -530,9 +527,8 @@ public class JournalEntryReadPlatformServiceImpl implements JournalEntryReadPlat
             final GLJournalEntryMapper rm = new GLJournalEntryMapper(associationParametersData);
             final String sql = "select " + rm.schema()
                     + " where journalEntry.transaction_id = ? and journalEntry.entity_id = ? and journalEntry.entity_type_enum = ?";
-            final String sqlCountRows = "SELECT FOUND_ROWS()";
             Object[] data = { transactionId, entityId, entityType };
-            return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sql, data, rm);
+            return this.paginationHelper.fetchPage(this.jdbcTemplate, sql, data, rm);
         } catch (final EmptyResultDataAccessException e) {
             throw new JournalEntriesNotFoundException(entityId, e);
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java
index af34266..99904ff 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/JournalEntryRunningBalanceUpdateServiceImpl.java
@@ -39,6 +39,7 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
 import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
@@ -62,41 +63,19 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
     private final JournalEntryDataValidator dataValidator;
 
     private final FromJsonHelper fromApiJsonHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     private final GLJournalEntryMapper entryMapper = new GLJournalEntryMapper();
 
-    // if a limit is not added to the running balance select statements below
-    // and the resultset is more than 400,000,
-    // the script will eat up all of the server memory
-    private final String selectRunningBalanceSqlLimit = "limit 0, 10000";
-
-    private final String officeRunningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
-            + "inner join (select max(id) as id from acc_gl_journal_entry where office_id=?  and entry_date < ? group by account_id,entry_date) je2 "
-            + "inner join (select max(entry_date) as date from acc_gl_journal_entry where office_id=? and entry_date < ? group by account_id) je3 "
-            + "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC "
-            + selectRunningBalanceSqlLimit;
-
-    private final String organizationRunningBalanceSql = "select je.organization_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
-            + "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by account_id,entry_date) je2 "
-            + "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by account_id) je3 "
-            + "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC "
-            + selectRunningBalanceSqlLimit;
-
-    private final String officesRunningBalanceSql = "select je.office_running_balance as runningBalance,je.account_id as accountId,je.office_id as officeId "
-            + "from acc_gl_journal_entry je "
-            + "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by office_id,account_id,entry_date) je2 "
-            + "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by office_id,account_id) je3 "
-            + "where je2.id = je.id and je.entry_date = je3.date group by je.id order by je.entry_date DESC "
-            + selectRunningBalanceSqlLimit;
-
     @Autowired
     public JournalEntryRunningBalanceUpdateServiceImpl(final RoutingDataSource dataSource,
             final OfficeRepositoryWrapper officeRepositoryWrapper, final JournalEntryDataValidator dataValidator,
-            final FromJsonHelper fromApiJsonHelper) {
+            final FromJsonHelper fromApiJsonHelper, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.officeRepositoryWrapper = officeRepositoryWrapper;
         this.dataValidator = dataValidator;
         this.fromApiJsonHelper = fromApiJsonHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -140,7 +119,12 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
         Map<Long, BigDecimal> runningBalanceMap = new HashMap<>(5);
         Map<Long, Map<Long, BigDecimal>> officesRunningBalance = new HashMap<>();
 
-        List<Map<String, Object>> list = jdbcTemplate.queryForList(organizationRunningBalanceSql, entityDate, entityDate);
+        List<Map<String, Object>> list = jdbcTemplate.queryForList(
+                "select je.organization_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
+                        + "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by account_id,entry_date) je2 ON je2.id = je.id "
+                        + "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by account_id) je3 ON je.entry_date = je3.date "
+                        + "group by je.id order by je.entry_date DESC " + sqlGenerator.limit(10000, 0),
+                entityDate, entityDate);
         for (Map<String, Object> entries : list) {
             Long accountId = Long.parseLong(entries.get("accountId").toString()); // Drizzle
                                                                                   // is
@@ -157,7 +141,12 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
             }
         }
 
-        List<Map<String, Object>> officesRunningBalanceList = jdbcTemplate.queryForList(officesRunningBalanceSql, entityDate, entityDate);
+        List<Map<String, Object>> officesRunningBalanceList = jdbcTemplate
+                .queryForList("select je.office_running_balance as runningBalance,je.account_id as accountId,je.office_id as officeId "
+                        + "from acc_gl_journal_entry je "
+                        + "inner join (select max(id) as id from acc_gl_journal_entry where entry_date < ? group by office_id,account_id,entry_date) je2 ON je2.id = je.id "
+                        + "inner join (select max(entry_date) as date from acc_gl_journal_entry where entry_date < ? group by office_id,account_id) je3 ON je.entry_date = je3.date "
+                        + "group by je.id order by je.entry_date DESC " + sqlGenerator.limit(10000, 0), entityDate, entityDate);
         for (Map<String, Object> entries : officesRunningBalanceList) {
             Long accountId = Long.parseLong(entries.get("accountId").toString());
             Long officeId = Long.parseLong(entries.get("officeId").toString());
@@ -212,7 +201,12 @@ public class JournalEntryRunningBalanceUpdateServiceImpl implements JournalEntry
     private void updateRunningBalance(Long officeId, Date entityDate) {
         Map<Long, BigDecimal> runningBalanceMap = new HashMap<>(5);
 
-        List<Map<String, Object>> list = jdbcTemplate.queryForList(officeRunningBalanceSql, officeId, entityDate, officeId, entityDate);
+        List<Map<String, Object>> list = jdbcTemplate.queryForList(
+                "select je.office_running_balance as runningBalance,je.account_id as accountId from acc_gl_journal_entry je "
+                        + "inner join (select max(id) as id from acc_gl_journal_entry where office_id=?  and entry_date < ? group by account_id,entry_date) je2 ON je2.id = je.id "
+                        + "inner join (select max(entry_date) as date from acc_gl_journal_entry where office_id=? and entry_date < ? group by account_id) je3 ON je.entry_date = je3.date "
+                        + "group by je.id order by je.entry_date DESC " + sqlGenerator.limit(10000, 0),
+                officeId, entityDate, officeId, entityDate);
         for (Map<String, Object> entries : list) {
             Long accountId = (Long) entries.get("accountId");
             if (!runningBalanceMap.containsKey(accountId)) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesReadPlatformServiceImpl.java
index a2ac521..8705fd5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/service/ProvisioningEntriesReadPlatformServiceImpl.java
@@ -32,6 +32,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,18 +47,23 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
     private static final Logger LOG = LoggerFactory.getLogger(ProvisioningEntriesReadPlatformServiceImpl.class);
     private final JdbcTemplate jdbcTemplate;
 
-    private final PaginationHelper<LoanProductProvisioningEntryData> loanProductProvisioningEntryDataPaginationHelper = new PaginationHelper<>();
-    private final PaginationHelper<ProvisioningEntryData> provisioningEntryDataPaginationHelper = new PaginationHelper<>();
+    private final PaginationHelper loanProductProvisioningEntryDataPaginationHelper;
+    private final PaginationHelper provisioningEntryDataPaginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
-    public ProvisioningEntriesReadPlatformServiceImpl(final RoutingDataSource dataSource) {
+    public ProvisioningEntriesReadPlatformServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.loanProductProvisioningEntryDataPaginationHelper = paginationHelper;
+        this.provisioningEntryDataPaginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
     public Collection<LoanProductProvisioningEntryData> retrieveLoanProductsProvisioningData(Date date) {
         String formattedDate = new SimpleDateFormat("yyyy-MM-dd").format(date);
-        LoanProductProvisioningEntryMapper mapper = new LoanProductProvisioningEntryMapper();
+        LoanProductProvisioningEntryMapper mapper = new LoanProductProvisioningEntryMapper(sqlGenerator);
         final String sql = mapper.schema();
         return this.jdbcTemplate.query(sql, mapper, new Object[] { formattedDate, formattedDate, formattedDate });
     }
@@ -66,17 +72,17 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
 
         private final StringBuilder sqlQuery;
 
-        private LoanProductProvisioningEntryMapper() {
+        private LoanProductProvisioningEntryMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
             sqlQuery = new StringBuilder().append(
                     "select (CASE WHEN loan.loan_type_enum=1 THEN mclient.office_id ELSE mgroup.office_id END) as office_id, loan.loan_type_enum, pcd.criteria_id as criteriaid, loan.product_id,loan.currency_code,")
-                    .append("GREATEST(datediff(?")
-                    .append(",sch.duedate),0) as numberofdaysoverdue,sch.duedate, pcd.category_id, pcd.provision_percentage,")
+                    .append("GREATEST(" + sqlGenerator.dateDiff("?", "sch.duedate")
+                            + ", 0) as numberofdaysoverdue,sch.duedate, pcd.category_id, pcd.provision_percentage,")
                     .append("loan.total_outstanding_derived as outstandingbalance, pcd.liability_account, pcd.expense_account from m_loan_repayment_schedule sch")
                     .append(" LEFT JOIN m_loan loan on sch.loan_id = loan.id")
                     .append(" JOIN m_loanproduct_provisioning_mapping lpm on lpm.product_id = loan.product_id")
                     .append(" JOIN m_provisioning_criteria_definition pcd on pcd.criteria_id = lpm.criteria_id and ")
-                    .append("(pcd.min_age <= GREATEST(datediff(?,sch.duedate),0) and GREATEST(datediff(?")
-                    .append(",sch.duedate),0) <= pcd.max_age) and pcd.criteria_id is not null ")
+                    .append("(pcd.min_age <= GREATEST(" + sqlGenerator.dateDiff("?", "sch.duedate") + ",0) and GREATEST("
+                            + sqlGenerator.dateDiff("?", "sch.duedate") + ",0) <= pcd.max_age) and pcd.criteria_id is not null ")
                     .append("LEFT JOIN m_client mclient ON mclient.id = loan.client_id ")
                     .append("LEFT JOIN m_group mgroup ON mgroup.id = loan.group_id ")
                     .append("where loan.loan_status_id=300 and sch.duedate = ")
@@ -221,7 +227,7 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
     public Page<ProvisioningEntryData> retrieveAllProvisioningEntries(Integer offset, Integer limit) {
         ProvisioningEntryDataMapper mapper = new ProvisioningEntryDataMapper();
         StringBuilder sqlBuilder = new StringBuilder();
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(mapper.getSchema());
         sqlBuilder.append(" order by entry.created_date");
         if (limit != null) {
@@ -231,10 +237,9 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
             sqlBuilder.append(" offset ").append(offset);
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] whereClauseItemsitems = new Object[] {};
-        return this.provisioningEntryDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
-                whereClauseItemsitems, mapper);
+        return this.provisioningEntryDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), whereClauseItemsitems,
+                mapper);
     }
 
     @Override
@@ -308,7 +313,7 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
     public Page<LoanProductProvisioningEntryData> retrieveProvisioningEntries(SearchParameters searchParams) {
         LoanProductProvisioningEntryRowMapper mapper = new LoanProductProvisioningEntryRowMapper();
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(mapper.getSchema());
         String whereClose = " where ";
         List<Object> items = new ArrayList<>();
@@ -344,8 +349,7 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
             }
         }
         Object[] whereClauseItemsitems = items.toArray();
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.loanProductProvisioningEntryDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
+        return this.loanProductProvisioningEntryDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(),
                 whereClauseItemsitems, mapper);
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/adhocquery/domain/AdHoc.java b/fineract-provider/src/main/java/org/apache/fineract/adhocquery/domain/AdHoc.java
index 2f7782a..9f36da6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/adhocquery/domain/AdHoc.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/adhocquery/domain/AdHoc.java
@@ -55,7 +55,7 @@ public final class AdHoc extends AbstractAuditableCustom {
     @Column(name = "report_run_every")
     private Long reportRunEvery;
 
-    @Column(name = "IsActive", nullable = false)
+    @Column(name = "is_active", nullable = false)
     private boolean isActive = false;
 
     private AdHoc() {}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocReadPlatformServiceImpl.java
index 56bf6c1..99bc58c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/adhocquery/service/AdHocReadPlatformServiceImpl.java
@@ -26,6 +26,7 @@ import org.apache.fineract.adhocquery.data.AdHocData;
 import org.apache.fineract.adhocquery.exception.AdHocNotFoundException;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -36,12 +37,14 @@ import org.springframework.stereotype.Service;
 public class AdHocReadPlatformServiceImpl implements AdHocReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final AdHocMapper adHocRowMapper;
 
     @Autowired
-    public AdHocReadPlatformServiceImpl(final RoutingDataSource dataSource) {
+    public AdHocReadPlatformServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
-        this.adHocRowMapper = new AdHocMapper();
+        this.sqlGenerator = sqlGenerator;
+        this.adHocRowMapper = new AdHocMapper(sqlGenerator);
     }
 
     @Override
@@ -53,7 +56,8 @@ public class AdHocReadPlatformServiceImpl implements AdHocReadPlatformService {
 
     @Override
     public Collection<AdHocData> retrieveAllActiveAdHocQuery() {
-        final String sql = "select " + this.adHocRowMapper.schema() + " where r.IsActive = true order by r.id";
+        final String sql = "select " + this.adHocRowMapper.schema() + " where r." + sqlGenerator.escape("is_active")
+                + " = true order by r.id";
 
         return this.jdbcTemplate.query(sql, this.adHocRowMapper);
     }
@@ -72,6 +76,12 @@ public class AdHocReadPlatformServiceImpl implements AdHocReadPlatformService {
 
     protected static final class AdHocMapper implements RowMapper<AdHocData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        public AdHocMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         @Override
         public AdHocData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
 
@@ -96,7 +106,7 @@ public class AdHocReadPlatformServiceImpl implements AdHocReadPlatformService {
         }
 
         public String schema() {
-            return " r.id as id, r.name as name, r.query as query, r.table_name as tableName,r.table_fields as tableField ,r.IsActive as isActive ,r.email as email ,"
+            return " r.id as id, r.name as name, r.query as query, r.table_name as tableName,r.table_fields as tableField ,r.is_active as isActive ,r.email as email ,"
                     + " r.report_run_frequency_code, r.report_run_every, r.last_run, "
                     + " r.created_date as createdDate, r.createdby_id as createdById,cb.username as createdBy,r.lastmodifiedby_id as updatedById ,r.lastmodified_date as updatedOn "
                     + " from m_adhoc r left join m_appuser cb on cb.id=r.createdby_id left join m_appuser mb on mb.id=r.lastmodifiedby_id";
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/AuditReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/commands/service/AuditReadPlatformServiceImpl.java
index dbf9d7b..a0b8365 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/commands/service/AuditReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/commands/service/AuditReadPlatformServiceImpl.java
@@ -43,6 +43,7 @@ import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.infrastructure.security.utils.SQLBuilder;
@@ -87,7 +88,8 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
     private final ClientReadPlatformService clientReadPlatformService;
     private final LoanProductReadPlatformService loanProductReadPlatformService;
     private final StaffReadPlatformService staffReadPlatformService;
-    private final PaginationHelper<AuditData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PaginationParametersDataValidator paginationParametersDataValidator;
     private final SavingsProductReadPlatformService savingsProductReadPlatformService;
     private final DepositProductReadPlatformService depositProductReadPlatformService;
@@ -100,7 +102,8 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
             final LoanProductReadPlatformService loanProductReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
             final PaginationParametersDataValidator paginationParametersDataValidator,
             final SavingsProductReadPlatformService savingsProductReadPlatformService,
-            final DepositProductReadPlatformService depositProductReadPlatformService, final ColumnValidator columnValidator) {
+            final DepositProductReadPlatformService depositProductReadPlatformService, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.fromApiJsonHelper = fromApiJsonHelper;
@@ -113,6 +116,8 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
         this.savingsProductReadPlatformService = savingsProductReadPlatformService;
         this.depositProductReadPlatformService = depositProductReadPlatformService;
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     private static final class AuditMapper implements RowMapper<AuditData> {
@@ -199,7 +204,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
 
         final AuditMapper rm = new AuditMapper();
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(rm.schema(includeJson, hierarchy));
         sqlBuilder.append(' ').append(extraCriteria.getSQLTemplate());
         if (parameters.isOrderByRequested()) {
@@ -216,8 +221,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
 
         LOG.info("sql: {}", sqlBuilder);
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), extraCriteria.getArguments(), rm);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), extraCriteria.getArguments(), rm);
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/domain/EmailCampaign.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/domain/EmailCampaign.java
index 72ac226..5ac15de 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/domain/EmailCampaign.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/domain/EmailCampaign.java
@@ -60,7 +60,7 @@ public class EmailCampaign extends AbstractPersistableCustom {
     private Integer campaignType;
 
     @ManyToOne
-    @JoinColumn(name = "businessRule_id", nullable = false)
+    @JoinColumn(name = "business_rule_id", nullable = false)
     private Report businessRuleId;
 
     @Column(name = "param_value")
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java
index 4d92ea2..c7ca45d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailCampaignReadPlatformServiceImpl.java
@@ -72,7 +72,7 @@ public class EmailCampaignReadPlatformServiceImpl implements EmailCampaignReadPl
             sql.append("ec.id as id, ");
             sql.append("ec.campaign_name as campaignName, ");
             sql.append("ec.campaign_type as campaignType, ");
-            sql.append("ec.businessRule_id as businessRuleId, ");
+            sql.append("ec.business_rule_id as businessRuleId, ");
             sql.append("ec.email_subject as emailSubject, ");
             sql.append("ec.email_message as emailMessage, ");
             sql.append("ec.email_attachment_file_format as emailAttachmentFileFormat, ");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailReadPlatformServiceImpl.java
index 71b8332..f16cff5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/email/service/EmailReadPlatformServiceImpl.java
@@ -36,6 +36,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -46,12 +47,16 @@ import org.springframework.stereotype.Service;
 public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final EmailMapper emailRowMapper = new EmailMapper();
-    private final PaginationHelper<EmailData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
-    public EmailReadPlatformServiceImpl(final RoutingDataSource dataSource) {
+    public EmailReadPlatformServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
+        this.paginationHelper = paginationHelper;
     }
 
     private static final class EmailMapper implements RowMapper<EmailData> {
@@ -129,7 +134,7 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
 
     @Override
     public Collection<EmailData> retrieveAllPending(final SearchParameters searchParameters) {
-        final String sqlPlusLimit = (searchParameters.getLimit() > 0) ? " limit 0, " + searchParameters.getLimit() : "";
+        final String sqlPlusLimit = (searchParameters.getLimit() > 0) ? " " + sqlGenerator.limit(searchParameters.getLimit()) : "";
         final String sql = "select " + this.emailRowMapper.schema() + " where emo.status_enum =? " + sqlPlusLimit;
 
         return this.jdbcTemplate.query(sql, this.emailRowMapper, EmailMessageStatusType.PENDING.getValue());
@@ -137,7 +142,7 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
 
     @Override
     public Collection<EmailData> retrieveAllSent(final SearchParameters searchParameters) {
-        final String sqlPlusLimit = (searchParameters.getLimit() > 0) ? " limit 0, " + searchParameters.getLimit() : "";
+        final String sqlPlusLimit = (searchParameters.getLimit() > 0) ? " " + sqlGenerator.limit(searchParameters.getLimit()) : "";
         final String sql = "select " + this.emailRowMapper.schema() + " where emo.status_enum = ?" + sqlPlusLimit;
 
         return this.jdbcTemplate.query(sql, this.emailRowMapper, EmailMessageStatusType.SENT.getValue());
@@ -145,7 +150,7 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
 
     @Override
     public List<Long> retrieveExternalIdsOfAllSent(final Integer limit) {
-        final String sqlPlusLimit = (limit > 0) ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = (limit > 0) ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select external_id from " + this.emailRowMapper.tableName() + " where status_enum =? " + sqlPlusLimit;
 
         return this.jdbcTemplate.queryForList(sql, Long.class, EmailMessageStatusType.SENT.getValue());
@@ -153,7 +158,7 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
 
     @Override
     public Collection<EmailData> retrieveAllDelivered(final Integer limit) {
-        final String sqlPlusLimit = (limit > 0) ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = (limit > 0) ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select " + this.emailRowMapper.schema() + " where emo.status_enum = ?" + sqlPlusLimit;
 
         return this.jdbcTemplate.query(sql, this.emailRowMapper, EmailMessageStatusType.DELIVERED.getValue());
@@ -161,7 +166,7 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
 
     @Override
     public Collection<EmailData> retrieveAllFailed(final SearchParameters searchParameters) {
-        final String sqlPlusLimit = (searchParameters.getLimit() > 0) ? " limit 0, " + searchParameters.getLimit() : "";
+        final String sqlPlusLimit = (searchParameters.getLimit() > 0) ? " " + sqlGenerator.limit(searchParameters.getLimit()) : "";
         final String sql = "select " + this.emailRowMapper.schema() + " where emo.status_enum = ?" + sqlPlusLimit;
 
         return this.jdbcTemplate.query(sql, this.emailRowMapper, EmailMessageStatusType.FAILED.getValue());
@@ -170,7 +175,7 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
     @Override
     public Page<EmailData> retrieveEmailByStatus(final Integer limit, final Integer status, final Date dateFrom, final Date dateTo) {
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.emailRowMapper.schema());
         if (status != null) {
             sqlBuilder.append(" where emo.status_enum= ? ");
@@ -183,12 +188,11 @@ public class EmailReadPlatformServiceImpl implements EmailReadPlatformService {
             toDateString = df.format(dateTo);
             sqlBuilder.append(" and emo.submittedon_date >= ? and emo.submittedon_date <= ? ");
         }
-        final String sqlPlusLimit = (limit > 0) ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = (limit > 0) ? " " + sqlGenerator.limit(limit) : "";
         if (!sqlPlusLimit.isEmpty()) {
             sqlBuilder.append(sqlPlusLimit);
         }
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(),
                 new Object[] { status, fromDateString, toDateString }, this.emailRowMapper);
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
index 89d7751..36824fa 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/campaigns/sms/service/SmsCampaignReadPlatformServiceImpl.java
@@ -42,6 +42,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.portfolio.calendar.service.CalendarDropdownReadPlatformService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataAccessException;
@@ -56,20 +57,24 @@ public class SmsCampaignReadPlatformServiceImpl implements SmsCampaignReadPlatfo
 
     private final BusinessRuleMapper businessRuleMapper;
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final SmsCampaignDropdownReadPlatformService smsCampaignDropdownReadPlatformService;
     private final SmsCampaignMapper smsCampaignMapper;
     private final CalendarDropdownReadPlatformService calendarDropdownReadPlatformService;
-    private final PaginationHelper<SmsCampaignData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
     public SmsCampaignReadPlatformServiceImpl(final RoutingDataSource dataSource,
             SmsCampaignDropdownReadPlatformService smsCampaignDropdownReadPlatformService,
-            final CalendarDropdownReadPlatformService calendarDropdownReadPlatformService) {
+            final CalendarDropdownReadPlatformService calendarDropdownReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
-        businessRuleMapper = new BusinessRuleMapper();
+        this.sqlGenerator = sqlGenerator;
+        this.businessRuleMapper = new BusinessRuleMapper(sqlGenerator);
         this.smsCampaignDropdownReadPlatformService = smsCampaignDropdownReadPlatformService;
-        smsCampaignMapper = new SmsCampaignMapper();
+        this.smsCampaignMapper = new SmsCampaignMapper();
         this.calendarDropdownReadPlatformService = calendarDropdownReadPlatformService;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -87,17 +92,18 @@ public class SmsCampaignReadPlatformServiceImpl implements SmsCampaignReadPlatfo
     public Page<SmsCampaignData> retrieveAll(final SearchParameters searchParameters) {
         final Integer visible = 1;
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.smsCampaignMapper.schema() + " where sc.is_visible = ? ");
+
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { visible },
-                this.smsCampaignMapper);
+        return this.paginationHelper.fetchPage(jdbcTemplate, sqlBuilder.toString(), new Object[] { visible }, this.smsCampaignMapper);
     }
 
     @Override
@@ -133,7 +139,7 @@ public class SmsCampaignReadPlatformServiceImpl implements SmsCampaignReadPlatfo
 
         final String schema;
 
-        private BusinessRuleMapper() {
+        private BusinessRuleMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
             final StringBuilder sql = new StringBuilder(300);
             sql.append("sr.id as id, ");
             sql.append("sr.report_name as reportName, ");
@@ -141,7 +147,7 @@ public class SmsCampaignReadPlatformServiceImpl implements SmsCampaignReadPlatfo
             sql.append("sr.report_subtype as reportSubType, ");
             sql.append("sr.description as description, ");
             sql.append("sp.parameter_variable as params, ");
-            sql.append("sp.parameter_FormatType as paramType, ");
+            sql.append("sp." + sqlGenerator.escape("parameter_FormatType") + " as paramType, ");
             sql.append("sp.parameter_label as paramLabel, ");
             sql.append("sp.parameter_name as paramName ");
             sql.append("from stretchy_report sr ");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/PersistenceConfig.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/PersistenceConfig.java
index 4b14812..071cbe5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/PersistenceConfig.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/PersistenceConfig.java
@@ -22,6 +22,7 @@ package org.apache.fineract.infrastructure.core.config;
 import javax.persistence.EntityManagerFactory;
 import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.domain.AuditorAwareImpl;
+import org.apache.fineract.infrastructure.openjpa.OpenJpaTransactionManager;
 import org.apache.fineract.infrastructure.openjpa.OpenJpaVendorAdapter;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -58,8 +59,8 @@ public class PersistenceConfig {
     }
 
     @Bean
-    public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
-        JpaTransactionManager jtm = new JpaTransactionManager();
+    public OpenJpaTransactionManager transactionManager(EntityManagerFactory emf) {
+        OpenJpaTransactionManager jtm = new OpenJpaTransactionManager();
         jtm.setEntityManagerFactory(emf);
         return jtm;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
index ddaaadf..a91c5ec 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/PaginationHelper.java
@@ -20,26 +20,46 @@ package org.apache.fineract.infrastructure.core.service;
 
 import java.util.List;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Component;
 
-public class PaginationHelper<E> {
+@Component
+public class PaginationHelper {
 
-    public Page<E> fetchPage(final JdbcTemplate jt, final String sqlCountRows, final String sqlFetchRows, final Object[] args,
-            final RowMapper<E> rowMapper) {
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
+    private final DatabaseTypeResolver databaseTypeResolver;
+
+    @Autowired
+    public PaginationHelper(DatabaseSpecificSQLGenerator sqlGenerator, DatabaseTypeResolver databaseTypeResolver) {
+        this.sqlGenerator = sqlGenerator;
+        this.databaseTypeResolver = databaseTypeResolver;
+    }
+
+    public <E> Page<E> fetchPage(final JdbcTemplate jt, final String sqlFetchRows, final Object[] args, final RowMapper<E> rowMapper) {
 
         final List<E> items = jt.query(sqlFetchRows, rowMapper, args);
 
         // determine how many rows are available
-        final int totalFilteredRecords = jt.queryForObject(sqlCountRows, Integer.class);
+        String sqlCountRows = sqlGenerator.countLastExecutedQueryResult(sqlFetchRows);
+        final int totalFilteredRecords;
+        if (databaseTypeResolver.isMySQL()) {
+            totalFilteredRecords = jt.queryForObject(sqlCountRows, Integer.class);
+        } else {
+            totalFilteredRecords = jt.queryForObject(sqlCountRows, Integer.class, args);
+        }
 
         return new Page<>(items, totalFilteredRecords);
     }
 
-    public Page<Long> fetchPage(JdbcTemplate jdbcTemplate, String sql, String sqlCountRows, Class<Long> type) {
+    public <E> Page<Long> fetchPage(JdbcTemplate jdbcTemplate, String sql, Class<Long> type) {
         final List<Long> items = jdbcTemplate.queryForList(sql, type);
 
         // determine how many rows are available
+        String sqlCountRows = sqlGenerator.countLastExecutedQueryResult(sql);
         Integer totalFilteredRecords = jdbcTemplate.queryForObject(sqlCountRows, Integer.class);
 
         return new Page<>(items, ObjectUtils.defaultIfNull(totalFilteredRecords, 0));
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java
index d472521..b62fba7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseIndependentQueryService.java
@@ -24,6 +24,7 @@ import java.sql.SQLException;
 import java.util.Collection;
 import javax.sql.DataSource;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.support.rowset.SqlRowSet;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -40,7 +41,7 @@ public class DatabaseIndependentQueryService implements DatabaseQueryService {
         try {
             DatabaseQueryService result = null;
             if (isNotEmpty(queryServices)) {
-                result = queryServices.stream().filter(qs -> qs.isSupported(dataSource)).findAny().orElse(null);
+                result = queryServices.stream().filter(DatabaseQueryService::isSupported).findAny().orElse(null);
             }
             if (result == null) {
                 throw new IllegalStateException("DataSource not supported: " + dataSource.getConnection().getMetaData().getURL());
@@ -52,7 +53,7 @@ public class DatabaseIndependentQueryService implements DatabaseQueryService {
     }
 
     @Override
-    public boolean isSupported(DataSource dataSource) {
+    public boolean isSupported() {
         return true;
     }
 
@@ -60,4 +61,9 @@ public class DatabaseIndependentQueryService implements DatabaseQueryService {
     public boolean isTablePresent(DataSource dataSource, String tableName) {
         return choose(dataSource).isTablePresent(dataSource, tableName);
     }
+
+    @Override
+    public SqlRowSet getTableColumns(DataSource dataSource, String tableName) {
+        return choose(dataSource).getTableColumns(dataSource, tableName);
+    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java
index 38fc65f..b004685 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseQueryService.java
@@ -19,10 +19,14 @@
 package org.apache.fineract.infrastructure.core.service.database;
 
 import javax.sql.DataSource;
+import org.springframework.jdbc.support.rowset.SqlRowSet;
 
 public interface DatabaseQueryService {
 
-    boolean isSupported(DataSource dataSource);
+    boolean isSupported();
 
     boolean isTablePresent(DataSource dataSource, String tableName);
+
+    // TODO: This needs to be improved to have a custom POJO return type instead of the raw SqlRowSet
+    SqlRowSet getTableColumns(DataSource dataSource, String tableName);
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java
new file mode 100644
index 0000000..9c3a20f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseSpecificSQLGenerator.java
@@ -0,0 +1,150 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.core.service.database;
+
+import static java.lang.String.format;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class DatabaseSpecificSQLGenerator {
+
+    private final DatabaseTypeResolver databaseTypeResolver;
+
+    @Autowired
+    public DatabaseSpecificSQLGenerator(DatabaseTypeResolver databaseTypeResolver) {
+        this.databaseTypeResolver = databaseTypeResolver;
+    }
+
+    public String escape(String arg) {
+        if (databaseTypeResolver.isMySQL()) {
+            return format("`%s`", arg);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return format("\"%s\"", arg);
+        }
+        return arg;
+    }
+
+    public String groupConcat(String arg) {
+        if (databaseTypeResolver.isMySQL()) {
+            return format("GROUP_CONCAT(%s)", arg);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            // STRING_AGG only works with strings
+            return format("STRING_AGG(%s::varchar, ',')", arg);
+        } else {
+            throw new IllegalStateException("Database type is not supported for group concat " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String limit(int count) {
+        return limit(count, 0);
+    }
+
+    public String limit(int count, int offset) {
+        if (databaseTypeResolver.isMySQL()) {
+            return format("LIMIT %s,%s", offset, count);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return format("LIMIT %s OFFSET %s", count, offset);
+        } else {
+            throw new IllegalStateException("Database type is not supported for limit " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String calcFoundRows() {
+        if (databaseTypeResolver.isMySQL()) {
+            return "SQL_CALC_FOUND_ROWS";
+        } else {
+            return "";
+        }
+    }
+
+    public String countLastExecutedQueryResult(String sql) {
+        if (databaseTypeResolver.isMySQL()) {
+            return "SELECT FOUND_ROWS()";
+        } else {
+            return countQueryResult(sql);
+        }
+    }
+
+    public String countQueryResult(String sql) {
+        return format("SELECT COUNT(*) FROM (%s) AS temp", sql);
+    }
+
+    public String currentDate() {
+        if (databaseTypeResolver.isMySQL()) {
+            return "CURDATE()";
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return "CURRENT_DATE";
+        } else {
+            throw new IllegalStateException("Database type is not supported for current date " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String subDate(String date, String multiplier, String unit) {
+        if (databaseTypeResolver.isMySQL()) {
+            return format("DATE_SUB(%s, INTERVAL %s %s)", date, multiplier, unit);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return format("(%s::TIMESTAMP - %s * INTERVAL '1 %s')", date, multiplier, unit);
+        } else {
+            throw new IllegalStateException("Database type is not supported for subtracting date " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String dateDiff(String date1, String date2) {
+        if (databaseTypeResolver.isMySQL()) {
+            return format("DATEDIFF(%s, %s)", date1, date2);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return format("EXTRACT(DAY FROM (%s::TIMESTAMP - %s::TIMESTAMP))", date1, date2);
+        } else {
+            throw new IllegalStateException("Database type is not supported for date diff " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String lastInsertId() {
+        if (databaseTypeResolver.isMySQL()) {
+            return "LAST_INSERT_ID()";
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return "LASTVAL()";
+        } else {
+            throw new IllegalStateException("Database type is not supported for last insert id " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String castChar(String sql) {
+        if (databaseTypeResolver.isMySQL()) {
+            return format("CAST(%s AS CHAR)", sql);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return format("%s::CHAR", sql);
+        } else {
+            throw new IllegalStateException(
+                    "Database type is not supported for casting to character " + databaseTypeResolver.databaseType());
+        }
+    }
+
+    public String currentSchema() {
+        if (databaseTypeResolver.isMySQL()) {
+            return "SCHEMA()";
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            return "CURRENT_SCHEMA()";
+        } else {
+            throw new IllegalStateException("Database type is not supported for current schema " + databaseTypeResolver.databaseType());
+        }
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
index feaea7d..6b3954d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseType.java
@@ -19,5 +19,5 @@
 package org.apache.fineract.infrastructure.core.service.database;
 
 public enum DatabaseType {
-    MYSQL
+    MYSQL, POSTGRESQL
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java
index bcfab30..b21bfb5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/DatabaseTypeResolver.java
@@ -18,53 +18,49 @@
  */
 package org.apache.fineract.infrastructure.core.service.database;
 
-import static org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection.toProtocol;
-
+import com.zaxxer.hikari.HikariConfig;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.sql.DataSource;
-import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import java.util.concurrent.atomic.AtomicReference;
+import org.springframework.beans.factory.InitializingBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
-public class DatabaseTypeResolver {
-
-    private final Map<String, DatabaseType> protocolMapping = Map.of("jdbc:mariadb", DatabaseType.MYSQL, "jdbc:mysql", DatabaseType.MYSQL);
+public class DatabaseTypeResolver implements InitializingBean {
 
-    private final Map<DataSource, DatabaseType> dataSourceCache = new ConcurrentHashMap<>();
+    private final Map<String, DatabaseType> driverMapping = Map.of("org.mariadb.jdbc.Driver", DatabaseType.MYSQL, "com.mysql.jdbc.Driver",
+            DatabaseType.MYSQL, "org.postgresql.Driver", DatabaseType.POSTGRESQL);
 
-    private final RoutingDataSource routingDataSource;
+    private final AtomicReference<DatabaseType> currentDatabaseType = new AtomicReference<>();
+    private final HikariConfig hikariConfig;
 
     @Autowired
-    public DatabaseTypeResolver(RoutingDataSource routingDataSource) {
-        this.routingDataSource = routingDataSource;
+    public DatabaseTypeResolver(HikariConfig hikariConfig) {
+        this.hikariConfig = hikariConfig;
     }
 
-    public boolean isMySQL() {
-        return isMySQL(routingDataSource);
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        currentDatabaseType.set(determineDatabaseType(hikariConfig.getDriverClassName()));
     }
 
-    public boolean isMySQL(DataSource dataSource) {
-        return DatabaseType.MYSQL.equals(databaseType(dataSource));
+    private DatabaseType determineDatabaseType(String driverClassName) {
+        DatabaseType databaseType = driverMapping.get(driverClassName);
+        if (databaseType == null) {
+            throw new IllegalArgumentException("The driver's class is not supported " + driverClassName);
+        }
+        return databaseType;
     }
 
     public DatabaseType databaseType() {
-        return databaseType(routingDataSource);
+        return currentDatabaseType.get();
     }
 
-    public DatabaseType databaseType(DataSource dataSource) {
-        DataSource unwrappedDataSource = dataSource;
-        if (dataSource instanceof RoutingDataSource) {
-            unwrappedDataSource = ((RoutingDataSource) dataSource).determineTargetDataSource();
-        }
-        return dataSourceCache.computeIfAbsent(unwrappedDataSource, (ds) -> {
-            String protocol = toProtocol(ds);
-            DatabaseType databaseType = protocolMapping.get(protocol);
-            if (databaseType == null) {
-                throw new IllegalArgumentException("The DataSource is not supported");
-            }
-            return databaseType;
-        });
+    public boolean isPostgreSQL() {
+        return DatabaseType.POSTGRESQL.equals(currentDatabaseType.get());
+    }
+
+    public boolean isMySQL() {
+        return DatabaseType.MYSQL.equals(currentDatabaseType.get());
     }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java
index 4896a5b..2e1493b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/MySQLQueryService.java
@@ -19,10 +19,9 @@
 package org.apache.fineract.infrastructure.core.service.database;
 
 import static java.lang.String.format;
-import static org.apache.fineract.infrastructure.core.domain.FineractPlatformTenantConnection.toProtocol;
 
-import java.util.Set;
 import javax.sql.DataSource;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.support.rowset.SqlRowSet;
 import org.springframework.stereotype.Component;
@@ -30,12 +29,16 @@ import org.springframework.stereotype.Component;
 @Component
 public class MySQLQueryService implements DatabaseQueryService {
 
-    private final Set<String> supportedProtocols = Set.of("jdbc:mariadb", "jdbc:mysql");
+    private final DatabaseTypeResolver databaseTypeResolver;
+
+    @Autowired
+    public MySQLQueryService(DatabaseTypeResolver databaseTypeResolver) {
+        this.databaseTypeResolver = databaseTypeResolver;
+    }
 
     @Override
-    public boolean isSupported(DataSource dataSource) {
-        String protocol = toProtocol(dataSource);
-        return supportedProtocols.contains(protocol.toLowerCase());
+    public boolean isSupported() {
+        return databaseTypeResolver.isMySQL();
     }
 
     @Override
@@ -44,4 +47,17 @@ public class MySQLQueryService implements DatabaseQueryService {
         SqlRowSet rs = jdbcTemplate.queryForRowSet(format("SHOW TABLES LIKE '%s'", tableName));
         return rs.next();
     }
+
+    @Override
+    public SqlRowSet getTableColumns(DataSource dataSource, String tableName) {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+        String sql = "SELECT c.COLUMN_NAME, c.IS_NULLABLE, c.DATA_TYPE, c.CHARACTER_MAXIMUM_LENGTH, c.COLUMN_KEY FROM INFORMATION_SCHEMA.COLUMNS c WHERE TABLE_SCHEMA = schema() AND TABLE_NAME = '"
+                + tableName + "' ORDER BY ORDINAL_POSITION";
+        final SqlRowSet columnDefinitions = jdbcTemplate.queryForRowSet(sql);
+        if (columnDefinitions.next()) {
+            return columnDefinitions;
+        } else {
+            throw new IllegalArgumentException("Table " + tableName + " is not found");
+        }
+    }
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java
new file mode 100644
index 0000000..428b822
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/PostgreSQLQueryService.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.core.service.database;
+
+import static java.lang.String.format;
+
+import java.util.Objects;
+import javax.sql.DataSource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.support.rowset.SqlRowSet;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PostgreSQLQueryService implements DatabaseQueryService {
+
+    private final DatabaseTypeResolver databaseTypeResolver;
+
+    @Autowired
+    public PostgreSQLQueryService(DatabaseTypeResolver databaseTypeResolver) {
+        this.databaseTypeResolver = databaseTypeResolver;
+    }
+
+    @Override
+    public boolean isSupported() {
+        return databaseTypeResolver.isPostgreSQL();
+    }
+
+    @Override
+    public boolean isTablePresent(DataSource dataSource, String tableName) {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+        Integer result = jdbcTemplate.queryForObject(format("SELECT COUNT(table_name) " + "FROM information_schema.tables "
+                + "WHERE table_schema = 'public' " + "AND table_name = '%s';", tableName), Integer.class);
+        return Objects.equals(result, 1);
+    }
+
+    @Override
+    public SqlRowSet getTableColumns(DataSource dataSource, String tableName) {
+        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
+        String sql = "SELECT attname AS COLUMN_NAME, not attnotnull AS IS_NULLABLE, atttypid::regtype  AS DATATYPE, attlen AS CHARACTER_MAXIMUM_LENGTH, attnum = 1 AS COLUMN_KEY FROM pg_attribute WHERE attrelid = '\""
+                + tableName + "\"'::regclass AND attnum > 0 AND NOT attisdropped ORDER BY attnum";
+        final SqlRowSet columnDefinitions = jdbcTemplate.queryForRowSet(sql);
+        if (columnDefinitions.next()) {
+            return columnDefinitions;
+        } else {
+            throw new IllegalArgumentException("Table " + tableName + " is not found");
+        }
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/DatabaseAwareMigrationContextProvider.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/DatabaseAwareMigrationContextProvider.java
index 2f27b08..580e6ab 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/DatabaseAwareMigrationContextProvider.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/DatabaseAwareMigrationContextProvider.java
@@ -19,7 +19,6 @@
 package org.apache.fineract.infrastructure.core.service.migration;
 
 import java.util.Map;
-import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseType;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -28,7 +27,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class DatabaseAwareMigrationContextProvider {
 
-    private final Map<DatabaseType, String> contextMapping = Map.of(DatabaseType.MYSQL, "mysql");
+    private final Map<DatabaseType, String> contextMapping = Map.of(DatabaseType.MYSQL, "mysql", DatabaseType.POSTGRESQL, "postgresql");
 
     private final DatabaseTypeResolver databaseTypeResolver;
 
@@ -37,8 +36,8 @@ public class DatabaseAwareMigrationContextProvider {
         this.databaseTypeResolver = databaseTypeResolver;
     }
 
-    public String provide(DataSource dataSource) {
-        DatabaseType databaseType = databaseTypeResolver.databaseType(dataSource);
+    public String provide() {
+        DatabaseType databaseType = databaseTypeResolver.databaseType();
         String context = contextMapping.get(databaseType);
         if (context == null) {
             throw new IllegalStateException("Database is not supported");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/ExtendedSpringLiquibaseFactory.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/ExtendedSpringLiquibaseFactory.java
index 4c40e35..85de2b3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/ExtendedSpringLiquibaseFactory.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/migration/ExtendedSpringLiquibaseFactory.java
@@ -43,7 +43,7 @@ public class ExtendedSpringLiquibaseFactory {
     }
 
     public ExtendedSpringLiquibase create(DataSource dataSource, String... contexts) {
-        String databaseContext = databaseAwareMigrationContextProvider.provide(dataSource);
+        String databaseContext = databaseAwareMigrationContextProvider.provide();
         return new ExtendedSpringLiquibaseBuilder(liquibaseProperties).withDataSource(dataSource).withResourceLoader(resourceLoader)
                 .withContexts(contexts).withContexts(environment.getActiveProfiles()).withContext(databaseContext).build();
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportReadPlatformServiceImpl.java
index 9209336..7e52c03 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/data/CreditReportReadPlatformServiceImpl.java
@@ -44,7 +44,7 @@ public class CreditReportReadPlatformServiceImpl implements CreditReportReadPlat
     private static final class CreditReportDataMapper implements RowMapper<CreditReportData> {
 
         public String schema() {
-            return " c.id as id, c.creditBureauId as creditBureauId , c.nationalId as nationalId from m_creditreport c ";
+            return " c.id as id, c.credit_bureau_id as creditBureauId , c.national_id as nationalId from m_creditreport c ";
         }
 
         @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureau.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureau.java
index 565dbbc..2bf30d3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureau.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureau.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.infrastructure.creditbureau.domain;
 
 import java.util.List;
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Table;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
@@ -34,6 +35,7 @@ public class CreditBureau extends AbstractPersistableCustom {
 
     private String country;
 
+    @Column(name = "implementation_key")
     private String implementationKey;
 
     public CreditBureau(String name, String product, String country, String implementationKey,
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauLoanProductMapping.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauLoanProductMapping.java
index 41b4de8..a7a603f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauLoanProductMapping.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauLoanProductMapping.java
@@ -33,15 +33,16 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
 @Table(name = "m_creditbureau_loanproduct_mapping")
 public class CreditBureauLoanProductMapping extends AbstractPersistableCustom {
 
-    @Column(name = "is_CreditCheck_Mandatory")
+    @Column(name = "is_credit_check_mandatory")
     private boolean isCreditCheckMandatory;
 
-    @Column(name = "skip_CreditCheck_in_Failure")
+    @Column(name = "skip_credit_check_in_failure")
     private boolean skipCreditCheckInFailure;
 
-    @Column(name = "stale_Period")
+    @Column(name = "stale_period")
     private int stalePeriod;
 
+    @Column(name = "is_active")
     private boolean isActive;
 
     @ManyToOne
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
index 34843af..3734dff 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditBureauToken.java
@@ -43,16 +43,16 @@ public class CreditBureauToken extends AbstractPersistableCustom {
     @Column(name = "token")
     private String accessToken;
 
-    @Column(name = "tokenType")
+    @Column(name = "token_type")
     private String tokenType;
 
-    @Column(name = "expiresIn")
+    @Column(name = "expires_in")
     private String expiresIn;
 
     @Column(name = "issued")
     private String issued;
 
-    @Column(name = "expiryDate")
+    @Column(name = "expiry_date")
     private Date expires;
 
     public static CreditBureauToken fromJson(final JsonCommand command) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReport.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReport.java
index c017288..0a0a8d8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReport.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/CreditReport.java
@@ -29,14 +29,14 @@ import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
 @Table(name = "m_creditreport")
 public final class CreditReport extends AbstractPersistableCustom {
 
-    @Column(name = "creditBureauId")
+    @Column(name = "credit_bureau_id")
     private Long creditBureauId;
 
-    @Column(name = "nationalId")
+    @Column(name = "national_id")
     private String nationalId;
 
     @Basic(fetch = FetchType.LAZY)
-    @Column(name = "creditReports")
+    @Column(name = "credit_reports")
     private byte[] creditReports;
 
     private CreditReport() {}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/OrganisationCreditBureau.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/OrganisationCreditBureau.java
index ee98338..b9ebda9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/OrganisationCreditBureau.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/domain/OrganisationCreditBureau.java
@@ -21,6 +21,7 @@ package org.apache.fineract.infrastructure.creditbureau.domain;
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.CascadeType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
@@ -37,6 +38,7 @@ public class OrganisationCreditBureau extends AbstractPersistableCustom {
     @OneToOne
     private CreditBureau creditbureau;
 
+    @Column(name = "is_active")
     private boolean isActive;
 
     @OneToMany(mappedBy = "organisation_creditbureau", cascade = CascadeType.ALL)
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauLoanProductMappingReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauLoanProductMappingReadPlatformServiceImpl.java
index 06ce1ca..a7b38e4 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauLoanProductMappingReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauLoanProductMappingReadPlatformServiceImpl.java
@@ -48,7 +48,7 @@ public class CreditBureauLoanProductMappingReadPlatformServiceImpl implements Cr
             return "cblp.id as mappingId, cblp.organisation_creditbureau_id as orgcbId,"
                     + "orgcb.alias as alias,concat( cb.product,' - ' ,cb.name,' - ',cb.country) as creditbureau,"
                     + "cblp.loan_product_id as lpId,lp.name as loan_product_name,cblp.is_creditcheck_mandatory as crCheck,cblp.skip_creditcheck_in_failure as skipcheck,"
-                    + "cblp.stale_period as staleperiod,cblp.isActive as isActive from"
+                    + "cblp.stale_period as staleperiod,cblp.is_active as isActive from"
                     + " m_creditbureau_loanproduct_mapping cblp, m_organisation_creditbureau orgcb,m_product_loan lp,m_creditbureau cb"
                     + " where cblp.organisation_creditbureau_id=orgcb.id and cblp.loan_product_id=lp.id and orgcb.creditbureau_id=cb.id";
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReadPlatformServiceImpl.java
index 6ca410f..2f33d6e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/CreditBureauReadPlatformServiceImpl.java
@@ -45,7 +45,7 @@ public class CreditBureauReadPlatformServiceImpl implements CreditBureauReadPlat
 
         public String schema() {
             return "cb.id as creditBureauID,cb.name as creditBureauName,cb.product as creditBureauProduct,"
-                    + "cb.country as country,concat(cb.product,' - ',cb.name,' - ',cb.country) as cbSummary,cb.implementationKey as implementationKey from m_creditbureau cb";
+                    + "cb.country as country,concat(cb.product,' - ',cb.name,' - ',cb.country) as cbSummary,cb.implementation_key as implementationKey from m_creditbureau cb";
         }
 
         @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/OrganisationCreditBureauReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/OrganisationCreditBureauReadPlatformServiceImpl.java
index a65962c..2a92d09 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/OrganisationCreditBureauReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/creditbureau/service/OrganisationCreditBureauReadPlatformServiceImpl.java
@@ -46,7 +46,7 @@ public class OrganisationCreditBureauReadPlatformServiceImpl implements Organisa
         public String schema() {
             return "ocb.id as orgCbId,ocb.alias as orgCbAlias,cb.name as creditbureauName,cb.product as creditbureauProduct,cb.country as creditbureauCountry,"
                     + "concat(cb.product,' - ',cb.name,' - ',cb.country) as CreditBureauSummary,"
-                    + "ocb.creditbureau_id as cbid,ocb.isActive  as isActive"
+                    + "ocb.creditbureau_id as cbid,ocb.is_active  as isActive"
                     + " from m_organisation_creditbureau ocb,m_creditbureau cb where ocb.creditbureau_id=cb.id";
 
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/data/ResultsetColumnHeaderData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/data/ResultsetColumnHeaderData.java
index 32023ab..485d460 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/data/ResultsetColumnHeaderData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/data/ResultsetColumnHeaderData.java
@@ -166,7 +166,8 @@ public final class ResultsetColumnHeaderData implements Serializable {
     }
 
     private boolean isDateTime() {
-        return "datetime".equalsIgnoreCase(this.columnType);
+        return "datetime".equalsIgnoreCase(this.columnType) || "timestamp without time zone".equalsIgnoreCase(this.columnType)
+                || "timestamptz".equalsIgnoreCase(this.columnType) || "timestamp with time zone".equalsIgnoreCase(this.columnType);
     }
 
     public boolean isString() {
@@ -174,7 +175,7 @@ public final class ResultsetColumnHeaderData implements Serializable {
     }
 
     private boolean isChar() {
-        return "char".equalsIgnoreCase(this.columnType);
+        return "char".equalsIgnoreCase(this.columnType) || "CHARACTER VARYING".equalsIgnoreCase(this.columnType);
     }
 
     private boolean isVarchar() {
@@ -190,7 +191,7 @@ public final class ResultsetColumnHeaderData implements Serializable {
     }
 
     private boolean isInteger() {
-        return "integer".equalsIgnoreCase(this.columnType);
+        return "integer".equalsIgnoreCase(this.columnType) || "int4".equalsIgnoreCase(this.columnType);
     }
 
     private boolean isSmallInt() {
@@ -206,7 +207,7 @@ public final class ResultsetColumnHeaderData implements Serializable {
     }
 
     private boolean isBigInt() {
-        return "bigint".equalsIgnoreCase(this.columnType);
+        return "bigint".equalsIgnoreCase(this.columnType) || "int8".equalsIgnoreCase(this.columnType);
     }
 
     private boolean isLong() {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/EntityDatatableChecksReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/EntityDatatableChecksReadPlatformServiceImpl.java
index a8c44ae..408b06c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/EntityDatatableChecksReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/EntityDatatableChecksReadPlatformServiceImpl.java
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.dataqueries.data.DatatableCheckStatusData;
 import org.apache.fineract.infrastructure.dataqueries.data.DatatableChecksData;
 import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
@@ -52,35 +53,39 @@ import org.springframework.stereotype.Service;
 public class EntityDatatableChecksReadPlatformServiceImpl implements EntityDatatableChecksReadService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final RegisterDataTableMapper registerDataTableMapper;
     private final EntityDataTableChecksMapper entityDataTableChecksMapper;
     private final EntityDatatableChecksRepository entityDatatableChecksRepository;
     private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
     private final LoanProductReadPlatformService loanProductReadPlatformService;
     private final SavingsProductReadPlatformService savingsProductReadPlatformService;
-    private final PaginationHelper<EntityDataTableChecksData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
     public EntityDatatableChecksReadPlatformServiceImpl(final RoutingDataSource dataSource,
             final LoanProductReadPlatformService loanProductReadPlatformService,
             final SavingsProductReadPlatformService savingsProductReadPlatformService,
             final EntityDatatableChecksRepository entityDatatableChecksRepository,
-            final ReadWriteNonCoreDataService readWriteNonCoreDataService) {
+            final ReadWriteNonCoreDataService readWriteNonCoreDataService, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
 
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
         this.registerDataTableMapper = new RegisterDataTableMapper();
         this.entityDataTableChecksMapper = new EntityDataTableChecksMapper();
         this.loanProductReadPlatformService = loanProductReadPlatformService;
         this.savingsProductReadPlatformService = savingsProductReadPlatformService;
         this.entityDatatableChecksRepository = entityDatatableChecksRepository;
         this.readWriteNonCoreDataService = readWriteNonCoreDataService;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
     public Page<EntityDataTableChecksData> retrieveAll(SearchParameters searchParameters, final Long status, final String entity,
             final Long productId) {
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.entityDataTableChecksMapper.schema());
 
         if (status != null || entity != null || productId != null) {
@@ -101,15 +106,16 @@ public class EntityDatatableChecksReadPlatformServiceImpl implements EntityDatat
             sqlBuilder.append(" and t.product_id = ? ");
             paramList.add(productId);
         }
+
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(jdbcTemplate, sqlCountRows, sqlBuilder.toString(), paramList.toArray(),
-                entityDataTableChecksMapper);
+        return this.paginationHelper.fetchPage(jdbcTemplate, sqlBuilder.toString(), paramList.toArray(), entityDataTableChecksMapper);
 
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java
index 8c11f88..7a3956a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/GenericDataServiceImpl.java
@@ -26,6 +26,9 @@ import java.util.List;
 import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseIndependentQueryService;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
 import org.apache.fineract.infrastructure.dataqueries.data.GenericResultsetData;
 import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeaderData;
 import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnValueData;
@@ -45,11 +48,18 @@ public class GenericDataServiceImpl implements GenericDataService {
 
     private final JdbcTemplate jdbcTemplate;
     private final DataSource dataSource;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
+    private final DatabaseTypeResolver databaseTypeResolver;
+    private final DatabaseIndependentQueryService databaseIndependentQueryService;
     private static final Logger LOG = LoggerFactory.getLogger(GenericDataServiceImpl.class);
 
     @Autowired
-    public GenericDataServiceImpl(final RoutingDataSource dataSource) {
+    public GenericDataServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator,
+            DatabaseTypeResolver databaseTypeResolver, DatabaseIndependentQueryService databaseIndependentQueryService) {
         this.dataSource = dataSource;
+        this.sqlGenerator = sqlGenerator;
+        this.databaseTypeResolver = databaseTypeResolver;
+        this.databaseIndependentQueryService = databaseIndependentQueryService;
         this.jdbcTemplate = new JdbcTemplate(this.dataSource);
 
     }
@@ -205,14 +215,14 @@ public class GenericDataServiceImpl implements GenericDataService {
 
         columnDefinitions.beforeFirst();
         while (columnDefinitions.next()) {
-            final String columnName = columnDefinitions.getString("COLUMN_NAME");
-            final String isNullable = columnDefinitions.getString("IS_NULLABLE");
-            final String isPrimaryKey = columnDefinitions.getString("COLUMN_KEY");
-            final String columnType = columnDefinitions.getString("DATA_TYPE");
-            final Long columnLength = columnDefinitions.getLong("CHARACTER_MAXIMUM_LENGTH");
+            final String columnName = columnDefinitions.getString(1);
+            final String isNullable = columnDefinitions.getString(2);
+            final String isPrimaryKey = columnDefinitions.getString(5);
+            final String columnType = columnDefinitions.getString(3);
+            final Long columnLength = columnDefinitions.getLong(4);
 
-            final boolean columnNullable = "YES".equalsIgnoreCase(isNullable);
-            final boolean columnIsPrimaryKey = "PRI".equalsIgnoreCase(isPrimaryKey);
+            final boolean columnNullable = "YES".equalsIgnoreCase(isNullable) || "TRUE".equalsIgnoreCase(isNullable);
+            final boolean columnIsPrimaryKey = "PRI".equalsIgnoreCase(isPrimaryKey) || "TRUE".equalsIgnoreCase(isPrimaryKey);
 
             List<ResultsetColumnValueData> columnValues = new ArrayList<>();
             String codeName = null;
@@ -295,18 +305,13 @@ public class GenericDataServiceImpl implements GenericDataService {
         return columnValues;
     }
 
+    @SuppressWarnings("AvoidHidingCauseException")
     private SqlRowSet getDatatableMetaData(final String datatable) {
-
-        final String sql = "select COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY"
-                + " from INFORMATION_SCHEMA.COLUMNS " + " where TABLE_SCHEMA = schema() and TABLE_NAME = '" + datatable
-                + "'order by ORDINAL_POSITION";
-
-        final SqlRowSet columnDefinitions = this.jdbcTemplate.queryForRowSet(sql);
-        if (columnDefinitions.next()) {
-            return columnDefinitions;
+        try {
+            return databaseIndependentQueryService.getTableColumns(dataSource, datatable);
+        } catch (IllegalArgumentException e) {
+            throw new DatatableNotFoundException(datatable);
         }
-
-        throw new DatatableNotFoundException(datatable);
     }
 
     private SqlRowSet getDatatableCodeData(final String datatable, final String columnName) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
index 2f39013..58982f7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
@@ -56,6 +56,8 @@ import org.apache.fineract.infrastructure.core.serialization.DatatableCommandFro
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
 import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
 import org.apache.fineract.infrastructure.dataqueries.data.DataTableValidator;
 import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
@@ -92,15 +94,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
     private static final String CODE_VALUES_TABLE = "m_code_value";
 
     private static final Logger LOG = LoggerFactory.getLogger(ReadWriteNonCoreDataServiceImpl.class);
+
+    // TODO: Extract these types out of here
     private static final ImmutableMap<String, String> apiTypeToMySQL = ImmutableMap.<String, String>builder().put("string", "VARCHAR")
             .put("number", "INT").put("boolean", "BIT").put("decimal", "DECIMAL").put("date", "DATE").put("datetime", "DATETIME")
             .put("text", "TEXT").put("dropdown", "INT").build();
+    private static final ImmutableMap<String, String> apiTypeToPostgreSQL = ImmutableMap.<String, String>builder().put("string", "VARCHAR")
+            .put("number", "INT").put("boolean", "BIT").put("decimal", "DECIMAL").put("date", "DATE").put("datetime", "TIMESTAMP")
+            .put("text", "TEXT").put("dropdown", "INT").build();
 
     private static final List<String> stringDataTypes = Arrays.asList("char", "varchar", "blob", "text", "tinyblob", "tinytext",
             "mediumblob", "mediumtext", "longblob", "longtext");
 
     private final JdbcTemplate jdbcTemplate;
     private final DataSource dataSource;
+    private final DatabaseTypeResolver databaseTypeResolver;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PlatformSecurityContext context;
     private final FromJsonHelper fromJsonHelper;
     private final JsonParserHelper helper;
@@ -120,8 +129,10 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             final FromJsonHelper fromJsonHelper, final GenericDataService genericDataService,
             final DatatableCommandFromApiJsonDeserializer fromApiJsonDeserializer, final CodeReadPlatformService codeReadPlatformService,
             final ConfigurationDomainService configurationDomainService, final DataTableValidator dataTableValidator,
-            final ColumnValidator columnValidator) {
+            final ColumnValidator columnValidator, DatabaseTypeResolver databaseTypeResolver, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.dataSource = dataSource;
+        this.databaseTypeResolver = databaseTypeResolver;
+        this.sqlGenerator = sqlGenerator;
         this.jdbcTemplate = new JdbcTemplate(this.dataSource);
         this.context = context;
         this.fromJsonHelper = fromJsonHelper;
@@ -487,8 +498,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
     }
 
     private void assertDataTableExists(final String datatableName) {
-        final String sql = "select (CASE WHEN exists (select 1 from information_schema.tables where table_schema = schema()"
-                + " and table_name = ?) THEN 'true' ELSE 'false' END)";
+        final String sql = "select (CASE WHEN exists (select 1 from information_schema.tables where table_schema = "
+                + sqlGenerator.currentSchema() + " and table_name = ?) THEN 'true' ELSE 'false' END)";
         final String dataTableExistsString = this.jdbcTemplate.queryForObject(sql, String.class, new Object[] { datatableName });
         final boolean dataTableExists = Boolean.valueOf(dataTableExistsString);
         if (!dataTableExists) {
@@ -532,15 +543,24 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         if (StringUtils.isNotBlank(code)) {
             if (isConstraintApproach) {
                 codeMappings.put(dataTableNameAlias + "_" + name, this.codeReadPlatformService.retriveCode(code).getCodeId());
-                constrainBuilder.append(", CONSTRAINT `fk_").append(dataTableNameAlias).append("_").append(name).append("` ")
-                        .append("FOREIGN KEY (`" + name + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE).append("` (`id`)");
+                String fkName = "fk_" + dataTableNameAlias + "_" + name;
+                constrainBuilder.append(", CONSTRAINT ").append(sqlGenerator.escape(fkName)).append(" ")
+                        .append("FOREIGN KEY (" + sqlGenerator.escape(name) + ") ").append("REFERENCES ")
+                        .append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (id)");
             } else {
                 name = datatableColumnNameToCodeValueName(name, code);
             }
         }
 
-        final String mysqlType = apiTypeToMySQL.get(type);
-        sqlBuilder = sqlBuilder.append("`" + name + "` " + mysqlType);
+        final String dataType;
+        if (databaseTypeResolver.isMySQL()) {
+            dataType = apiTypeToMySQL.get(type);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            dataType = apiTypeToPostgreSQL.get(type);
+        } else {
+            throw new IllegalStateException("Current database is not supported");
+        }
+        sqlBuilder = sqlBuilder.append(sqlGenerator.escape(name) + " " + dataType);
 
         if (type != null) {
             if (type.equalsIgnoreCase("String")) {
@@ -599,12 +619,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             StringBuilder sqlBuilder = new StringBuilder();
             final StringBuilder constrainBuilder = new StringBuilder();
             final Map<String, Long> codeMappings = new HashMap<>();
-            sqlBuilder = sqlBuilder.append("CREATE TABLE `" + datatableName + "` (");
+            sqlBuilder = sqlBuilder.append("CREATE TABLE " + sqlGenerator.escape(datatableName) + " (");
 
             if (multiRow) {
-                sqlBuilder = sqlBuilder.append("`id` BIGINT NOT NULL AUTO_INCREMENT, ").append("`" + fkColumnName + "` BIGINT NOT NULL, ");
+                sqlBuilder = sqlBuilder.append("id BIGINT NOT NULL AUTO_INCREMENT, ")
+                        .append(sqlGenerator.escape(fkColumnName) + " BIGINT NOT NULL, ");
             } else {
-                sqlBuilder = sqlBuilder.append("`" + fkColumnName + "` BIGINT NOT NULL, ");
+                sqlBuilder = sqlBuilder.append(sqlGenerator.escape(fkColumnName) + " BIGINT NOT NULL, ");
             }
 
             for (final JsonElement column : columns) {
@@ -615,19 +636,26 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             // Remove trailing comma and space
             sqlBuilder = sqlBuilder.delete(sqlBuilder.length() - 2, sqlBuilder.length());
 
+            String fullFkName = "fk_" + fkName;
             if (multiRow) {
-                sqlBuilder = sqlBuilder.append(", PRIMARY KEY (`id`)")
-                        .append(", KEY `fk_" + apptableName.substring(2) + "_id` (`" + fkColumnName + "`)")
-                        .append(", CONSTRAINT `fk_" + fkName + "` ").append("FOREIGN KEY (`" + fkColumnName + "`) ")
-                        .append("REFERENCES `" + actualAppTableName + "` (`id`)");
+                sqlBuilder = sqlBuilder.append(", PRIMARY KEY (id)")
+                        .append(", KEY " + sqlGenerator.escape("fk_" + apptableName.substring(2) + "_id") + " ("
+                                + sqlGenerator.escape(fkColumnName) + ")")
+                        .append(", CONSTRAINT " + sqlGenerator.escape(fullFkName) + " ")
+                        .append("FOREIGN KEY (" + sqlGenerator.escape(fkColumnName) + ") ")
+                        .append("REFERENCES " + sqlGenerator.escape(actualAppTableName) + " (id)");
             } else {
-                sqlBuilder = sqlBuilder.append(", PRIMARY KEY (`" + fkColumnName + "`)").append(", CONSTRAINT `fk_" + fkName + "` ")
-                        .append("FOREIGN KEY (`" + fkColumnName + "`) ").append("REFERENCES `" + actualAppTableName + "` (`id`)");
+                sqlBuilder = sqlBuilder.append(", PRIMARY KEY (" + sqlGenerator.escape(fkColumnName) + ")")
+                        .append(", CONSTRAINT " + sqlGenerator.escape(fullFkName) + " ")
+                        .append("FOREIGN KEY (" + sqlGenerator.escape(fkColumnName) + ") ")
+                        .append("REFERENCES " + sqlGenerator.escape(actualAppTableName) + " (id)");
             }
 
             sqlBuilder.append(constrainBuilder);
-
-            sqlBuilder = sqlBuilder.append(") ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;");
+            sqlBuilder.append(")");
+            if (databaseTypeResolver.isMySQL()) {
+                sqlBuilder.append(" ENGINE=InnoDB DEFAULT CHARSET=UTF8MB4;");
+            }
             this.jdbcTemplate.execute(sqlBuilder.toString());
 
             registerDatatable(datatableName, apptableName, entitySubType);
@@ -686,32 +714,33 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             if (StringUtils.isBlank(newName)) {
                 newName = name;
             }
+            String fkName = "fk_" + dataTableNameAlias + "_" + name;
+            String newFkName = "fk_" + dataTableNameAlias + "_" + newName;
             if (!StringUtils.equalsIgnoreCase(code, newCode) || !StringUtils.equalsIgnoreCase(name, newName)) {
                 if (StringUtils.equalsIgnoreCase(code, newCode)) {
                     final int codeId = getCodeIdForColumn(dataTableNameAlias, name);
                     if (codeId > 0) {
                         removeMappings.add(dataTableNameAlias + "_" + name);
-                        constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(dataTableNameAlias).append("_").append(name).append("` ");
+                        constrainBuilder.append(", DROP FOREIGN KEY ").append(sqlGenerator.escape(fkName)).append(" ");
                         codeMappings.put(dataTableNameAlias + "_" + newName, (long) codeId);
-                        constrainBuilder.append(",ADD CONSTRAINT  `fk_").append(dataTableNameAlias).append("_").append(newName).append("` ")
-                                .append("FOREIGN KEY (`" + newName + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE)
-                                .append("` (`id`)");
+                        constrainBuilder.append(",ADD CONSTRAINT ").append(sqlGenerator.escape(newFkName)).append(" ")
+                                .append("FOREIGN KEY (" + sqlGenerator.escape(newName) + ") ").append("REFERENCES ")
+                                .append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (id)");
                     }
 
                 } else {
                     if (code != null) {
                         removeMappings.add(dataTableNameAlias + "_" + name);
                         if (newCode == null || !StringUtils.equalsIgnoreCase(name, newName)) {
-                            constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(dataTableNameAlias).append("_").append(name)
-                                    .append("` ");
+                            constrainBuilder.append(", DROP FOREIGN KEY ").append(sqlGenerator.escape(fkName)).append(" ");
                         }
                     }
                     if (newCode != null) {
                         codeMappings.put(dataTableNameAlias + "_" + newName, this.codeReadPlatformService.retriveCode(newCode).getCodeId());
                         if (code == null || !StringUtils.equalsIgnoreCase(name, newName)) {
-                            constrainBuilder.append(",ADD CONSTRAINT  `fk_").append(dataTableNameAlias).append("_").append(newName)
-                                    .append("` ").append("FOREIGN KEY (`" + newName + "`) ").append("REFERENCES `")
-                                    .append(CODE_VALUES_TABLE).append("` (`id`)");
+                            constrainBuilder.append(",ADD CONSTRAINT  ").append(sqlGenerator.escape(newFkName)).append(" ")
+                                    .append("FOREIGN KEY (" + sqlGenerator.escape(newName) + ") ").append("REFERENCES ")
+                                    .append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (id)");
                         }
                     }
                 }
@@ -735,7 +764,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             length = mapColumnNameDefinition.get(name).getColumnLength().intValue();
         }
 
-        sqlBuilder = sqlBuilder.append(", CHANGE `" + name + "` `" + newName + "` " + type);
+        sqlBuilder = sqlBuilder.append(", CHANGE " + sqlGenerator.escape(name) + " " + sqlGenerator.escape(newName) + " " + type);
         if (length != null && length > 0) {
             if (type.toLowerCase().equals("decimal")) {
                 sqlBuilder.append("(19,6)");
@@ -751,7 +780,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         }
 
         if (after != null) {
-            sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`");
+            sqlBuilder = sqlBuilder.append(" AFTER " + sqlGenerator.escape(after));
         }
     }
 
@@ -781,16 +810,25 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
 
         if (StringUtils.isNotBlank(code)) {
             if (isConstraintApproach) {
+                String fkName = "fk_" + dataTableNameAlias + "_" + name;
                 codeMappings.put(dataTableNameAlias + "_" + name, this.codeReadPlatformService.retriveCode(code).getCodeId());
-                constrainBuilder.append(",ADD CONSTRAINT  `fk_").append(dataTableNameAlias).append("_").append(name).append("` ")
-                        .append("FOREIGN KEY (`" + name + "`) ").append("REFERENCES `").append(CODE_VALUES_TABLE).append("` (`id`)");
+                constrainBuilder.append(",ADD CONSTRAINT  ").append(sqlGenerator.escape(fkName)).append(" ")
+                        .append("FOREIGN KEY (" + sqlGenerator.escape(name) + ") ").append("REFERENCES ")
+                        .append(sqlGenerator.escape(CODE_VALUES_TABLE)).append(" (id)");
             } else {
                 name = datatableColumnNameToCodeValueName(name, code);
             }
         }
 
-        final String mysqlType = apiTypeToMySQL.get(type);
-        sqlBuilder = sqlBuilder.append(", ADD `" + name + "` " + mysqlType);
+        final String dataType;
+        if (databaseTypeResolver.isMySQL()) {
+            dataType = apiTypeToMySQL.get(type);
+        } else if (databaseTypeResolver.isPostgreSQL()) {
+            dataType = apiTypeToPostgreSQL.get(type);
+        } else {
+            throw new IllegalStateException("Current database is not supported");
+        }
+        sqlBuilder = sqlBuilder.append(", ADD " + sqlGenerator.escape(name) + " " + dataType);
 
         if (type != null) {
             if (type.equalsIgnoreCase("String") && length != null) {
@@ -809,7 +847,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         }
 
         if (after != null) {
-            sqlBuilder = sqlBuilder.append(" AFTER `" + after + "`");
+            sqlBuilder = sqlBuilder.append(" AFTER " + sqlGenerator.escape(after));
         }
     }
 
@@ -817,7 +855,6 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             final StringBuilder constrainBuilder, final List<String> codeMappings) {
         final String datatableAlias = datatableName.toLowerCase().replaceAll("\\s", "_");
         final String name = column.has("name") ? column.get("name").getAsString() : null;
-        // sqlBuilder = sqlBuilder.append(", DROP COLUMN `" + name + "`");
         final StringBuilder findFKSql = new StringBuilder();
         findFKSql.append("SELECT count(*)").append("FROM information_schema.TABLE_CONSTRAINTS i")
                 .append(" WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'").append(" AND i.TABLE_SCHEMA = DATABASE()")
@@ -825,8 +862,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                 .append("_").append(name).append("' ");
         final int count = this.jdbcTemplate.queryForObject(findFKSql.toString(), Integer.class);
         if (count > 0) {
+            String fkName = "fk_" + datatableAlias + "_" + name;
             codeMappings.add(datatableAlias + "_" + name);
-            constrainBuilder.append(", DROP FOREIGN KEY `fk_").append(datatableAlias).append("_").append(name).append("` ");
+            constrainBuilder.append(", DROP FOREIGN KEY ").append(sqlGenerator.escape(fkName)).append(" ");
         }
     }
 
@@ -875,7 +913,8 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         if (StringUtils.isNotEmpty(type)) {
             if (mandatory && stringDataTypes.contains(type.toLowerCase())) {
                 StringBuilder sqlBuilder = new StringBuilder();
-                sqlBuilder.append("UPDATE `" + datatableName + "` SET `" + name + "` = '' WHERE `" + name + "` IS NULL");
+                sqlBuilder.append("UPDATE " + sqlGenerator.escape(datatableName) + " SET " + sqlGenerator.escape(name) + " = '' WHERE "
+                        + sqlGenerator.escape(name) + " IS NULL");
 
                 this.jdbcTemplate.update(sqlBuilder.toString());
             }
@@ -908,7 +947,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             final boolean isConstraintApproach = this.configurationDomainService.isConstraintApproachEnabledForDatatables();
 
             if (!StringUtils.isBlank(entitySubType)) {
-                String updateLegalFormSQL = "update `x_registered_table` SET `entity_subtype`='" + entitySubType
+                String updateLegalFormSQL = "update x_registered_table SET entity_subtype='" + entitySubType
                         + "' WHERE registered_table_name = '" + datatableName + "'";
                 this.jdbcTemplate.execute(updateLegalFormSQL);
             }
@@ -925,19 +964,28 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                     final String newConstraintName = datatableName.toLowerCase().replaceAll("\\s", "_") + "_" + newFKName;
                     StringBuilder sqlBuilder = new StringBuilder();
 
+                    String fullOldFk = "fk_" + oldFKName;
+                    String fullOldConstraint = "fk_" + oldConstraintName;
+                    String fullNewFk = "fk_" + newFKName;
+                    String fullNewConstraint = "fk_" + newConstraintName;
                     if (mapColumnNameDefinition.containsKey("id")) {
-                        sqlBuilder = sqlBuilder.append("ALTER TABLE `" + datatableName + "` ").append("DROP KEY `fk_" + oldFKName + "`,")
-                                .append("DROP FOREIGN KEY `fk_" + oldConstraintName + "`,")
-                                .append("CHANGE COLUMN `" + oldFKName + "` `" + newFKName + "` BIGINT NOT NULL,")
-                                .append("ADD KEY `fk_" + newFKName + "` (`" + newFKName + "`),")
-                                .append("ADD CONSTRAINT `fk_" + newConstraintName + "` ").append("FOREIGN KEY (`" + newFKName + "`) ")
-                                .append("REFERENCES `" + actualAppTableName + "` (`id`)");
+                        sqlBuilder = sqlBuilder.append("ALTER TABLE " + sqlGenerator.escape(datatableName) + " ")
+                                .append("DROP KEY " + sqlGenerator.escape(fullOldFk) + ",")
+                                .append("DROP FOREIGN KEY " + sqlGenerator.escape(fullOldConstraint) + ",")
+                                .append("CHANGE COLUMN " + sqlGenerator.escape(oldFKName) + " " + sqlGenerator.escape(newFKName)
+                                        + " BIGINT NOT NULL,")
+                                .append("ADD KEY " + sqlGenerator.escape(fullNewFk) + " (" + sqlGenerator.escape(newFKName) + "),")
+                                .append("ADD CONSTRAINT " + sqlGenerator.escape(fullNewConstraint) + " ")
+                                .append("FOREIGN KEY (" + sqlGenerator.escape(newFKName) + ") ")
+                                .append("REFERENCES " + sqlGenerator.escape(actualAppTableName) + " (id)");
                     } else {
-                        sqlBuilder = sqlBuilder.append("ALTER TABLE `" + datatableName + "` ")
-                                .append("DROP FOREIGN KEY `fk_" + oldConstraintName + "`,")
-                                .append("CHANGE COLUMN `" + oldFKName + "` `" + newFKName + "` BIGINT NOT NULL,")
-                                .append("ADD CONSTRAINT `fk_" + newConstraintName + "` ").append("FOREIGN KEY (`" + newFKName + "`) ")
-                                .append("REFERENCES `" + actualAppTableName + "` (`id`)");
+                        sqlBuilder = sqlBuilder.append("ALTER TABLE " + sqlGenerator.escape(datatableName) + " ")
+                                .append("DROP FOREIGN KEY " + sqlGenerator.escape(fullOldConstraint) + ",")
+                                .append("CHANGE COLUMN " + sqlGenerator.escape(oldFKName) + " " + sqlGenerator.escape(newFKName)
+                                        + " BIGINT NOT NULL,")
+                                .append("ADD CONSTRAINT " + sqlGenerator.escape(fullNewConstraint) + " ")
+                                .append("FOREIGN KEY (" + sqlGenerator.escape(newFKName) + ") ")
+                                .append("REFERENCES " + sqlGenerator.escape(actualAppTableName) + " (id)");
                     }
 
                     this.jdbcTemplate.execute(sqlBuilder.toString());
@@ -956,14 +1004,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                     throw new GeneralPlatformDomainRuleException("error.msg.non.empty.datatable.column.cannot.be.deleted",
                             "Non-empty datatable columns can not be deleted.");
                 }
-                StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`");
+                StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE " + sqlGenerator.escape(datatableName));
                 final StringBuilder constrainBuilder = new StringBuilder();
                 final List<String> codeMappings = new ArrayList<>();
                 for (final JsonElement column : dropColumns) {
                     parseDatatableColumnForDrop(column.getAsJsonObject(), sqlBuilder, datatableName, constrainBuilder, codeMappings);
                 }
 
-                // Remove the first comma, right after ALTER TABLE `datatable`
+                // Remove the first comma, right after ALTER TABLE datatable
                 final int indexOfFirstComma = sqlBuilder.indexOf(",");
                 if (indexOfFirstComma != -1) {
                     sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
@@ -974,7 +1022,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             }
             if (addColumns != null) {
 
-                StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`");
+                StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE " + sqlGenerator.escape(datatableName));
                 final StringBuilder constrainBuilder = new StringBuilder();
                 final Map<String, Long> codeMappings = new HashMap<>();
                 for (final JsonElement column : addColumns) {
@@ -987,7 +1035,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                             constrainBuilder, codeMappings, isConstraintApproach);
                 }
 
-                // Remove the first comma, right after ALTER TABLE `datatable`
+                // Remove the first comma, right after ALTER TABLE datatable
                 final int indexOfFirstComma = sqlBuilder.indexOf(",");
                 if (indexOfFirstComma != -1) {
                     sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
@@ -998,7 +1046,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             }
             if (changeColumns != null) {
 
-                StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE `" + datatableName + "`");
+                StringBuilder sqlBuilder = new StringBuilder("ALTER TABLE " + sqlGenerator.escape(datatableName));
                 final StringBuilder constrainBuilder = new StringBuilder();
                 final Map<String, Long> codeMappings = new HashMap<>();
                 final List<String> removeMappings = new ArrayList<>();
@@ -1010,7 +1058,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                             constrainBuilder, codeMappings, removeMappings, isConstraintApproach);
                 }
 
-                // Remove the first comma, right after ALTER TABLE `datatable`
+                // Remove the first comma, right after ALTER TABLE datatable
                 final int indexOfFirstComma = sqlBuilder.indexOf(",");
                 if (indexOfFirstComma != -1) {
                     sqlBuilder = sqlBuilder.deleteCharAt(indexOfFirstComma);
@@ -1090,7 +1138,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
             } else {
                 sqlArray = new String[1];
             }
-            final String sql = "DROP TABLE `" + datatableName + "`";
+            final String sql = "DROP TABLE " + sqlGenerator.escape(datatableName);
             sqlArray[0] = sql;
             this.jdbcTemplate.batchUpdate(sqlArray);
         } catch (final JpaSystemException | DataIntegrityViolationException e) {
@@ -1114,7 +1162,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
     }
 
     private int getRowCount(final String datatableName) {
-        final String sql = "select count(*) from `" + datatableName + "`";
+        final String sql = "select count(*) from " + sqlGenerator.escape(datatableName);
         return this.jdbcTemplate.queryForObject(sql, Integer.class);
     }
 
@@ -1240,9 +1288,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         if (id == null) {
             String whereClause = getFKField(appTable) + " = " + appTableId;
             SQLInjectionValidator.validateSQLInput(whereClause);
-            sql = sql + "select * from `" + dataTableName + "` where " + whereClause;
+            sql = sql + "select * from " + sqlGenerator.escape(dataTableName) + " where " + whereClause;
         } else {
-            sql = sql + "select * from `" + dataTableName + "` where id = " + id;
+            sql = sql + "select * from " + sqlGenerator.escape(dataTableName) + " where id = " + id;
         }
 
         if (StringUtils.isNotBlank(order)) {
@@ -1267,9 +1315,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         if (id == null) {
             String whereClause = getFKField(appTable) + " = " + appTableId;
             SQLInjectionValidator.validateSQLInput(whereClause);
-            sql = sql + "select * from `" + dataTableName + "` where " + whereClause;
+            sql = sql + "select * from " + sqlGenerator.escape(dataTableName) + " where " + whereClause;
         } else {
-            sql = sql + "select * from `" + dataTableName + "` where id = " + id;
+            sql = sql + "select * from " + sqlGenerator.escape(dataTableName) + " where id = " + id;
         }
 
         final List<ResultsetRowData> result = fillDatatableResultSetDataRows(sql);
@@ -1328,22 +1376,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
          * means it relates to an m_client that is in a group (still an m_client account)
          */
         if (appTable.equalsIgnoreCase("m_loan")) {
-            scopedSQL = "select  distinctrow x.* from ("
+            scopedSQL = "select distinct x.* from ("
                     + " (select o.id as officeId, l.group_id as groupId, l.client_id as clientId, null as savingsId, l.id as loanId, null as entityId from m_loan l "
                     + " join m_client c on c.id = l.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '"
                     + currentUser.getOffice().getHierarchy() + "%'" + " where l.id = " + appTableId + ")" + " union all "
                     + " (select o.id as officeId, l.group_id as groupId, l.client_id as clientId, null as savingsId, l.id as loanId, null as entityId from m_loan l "
                     + " join m_group g on g.id = l.group_id " + " join m_office o on o.id = g.office_id and o.hierarchy like '"
-                    + currentUser.getOffice().getHierarchy() + "%'" + " where l.id = " + appTableId + ")" + " ) x";
+                    + currentUser.getOffice().getHierarchy() + "%'" + " where l.id = " + appTableId + ")" + " ) as x";
         }
         if (appTable.equalsIgnoreCase("m_savings_account")) {
-            scopedSQL = "select  distinctrow x.* from ("
+            scopedSQL = "select distinct x.* from ("
                     + " (select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, null as entityId from m_savings_account s "
                     + " join m_client c on c.id = s.client_id " + " join m_office o on o.id = c.office_id and o.hierarchy like '"
                     + currentUser.getOffice().getHierarchy() + "%'" + " where s.id = " + appTableId + ")" + " union all "
                     + " (select o.id as officeId, s.group_id as groupId, s.client_id as clientId, s.id as savingsId, null as loanId, null as entityId from m_savings_account s "
                     + " join m_group g on g.id = s.group_id " + " join m_office o on o.id = g.office_id and o.hierarchy like '"
-                    + currentUser.getOffice().getHierarchy() + "%'" + " where s.id = " + appTableId + ")" + " ) x";
+                    + currentUser.getOffice().getHierarchy() + "%'" + " where s.id = " + appTableId + ")" + " ) as x";
         }
         if (appTable.equalsIgnoreCase("m_client")) {
             scopedSQL = "select o.id as officeId, null as groupId, c.id as clientId, null as savingsId, null as loanId, null as entityId from m_client c "
@@ -1484,14 +1532,14 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                     }
 
                 }
-                columnName = "`" + key + "`";
+                columnName = sqlGenerator.escape(key);
                 insertColumns += ", " + columnName;
                 selectColumns += "," + pValueWrite + " as " + columnName;
             }
         }
 
-        addSql = "insert into `" + datatable + "` (`" + fkName + "` " + insertColumns + ")" + " select " + appTableId + " as id"
-                + selectColumns;
+        addSql = "insert into " + sqlGenerator.escape(datatable) + " (" + sqlGenerator.escape(fkName) + " " + insertColumns + ")"
+                + " select " + appTableId + " as id" + selectColumns;
 
         LOG.info("{}", addSql);
 
@@ -1532,16 +1580,16 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                 scoresId += pValueWrite + " ,";
 
             }
-            columnName = "`" + key + "`";
+            columnName = sqlGenerator.escape(key);
             insertColumns += ", " + columnName;
             selectColumns += "," + pValueWrite + " as " + columnName;
         }
 
         scoresId = scoresId.replaceAll(" ,$", "");
 
-        String vaddSql = "insert into `" + datatable + "` (`" + fkName + "` " + insertColumns + ", `score` )" + " select " + appTableId
-                + " as id" + selectColumns + " , ( SELECT SUM( code_score ) FROM m_code_value WHERE m_code_value.id IN (" + scoresId
-                + " ) ) as score";
+        String vaddSql = "insert into " + sqlGenerator.escape(datatable) + " (" + sqlGenerator.escape(fkName) + " " + insertColumns
+                + ", score )" + " select " + appTableId + " as id" + selectColumns
+                + " , ( SELECT SUM( code_score ) FROM m_code_value WHERE m_code_value.id IN (" + scoresId + " ) ) as score";
 
         LOG.info("{}", vaddSql);
 
@@ -1566,7 +1614,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
         String pValueWrite = "";
         final String singleQuote = "'";
         boolean firstColumn = true;
-        String sql = "update `" + datatable + "` ";
+        String sql = "update " + sqlGenerator.escape(datatable) + " ";
         for (final ResultsetColumnHeaderData pColumnHeader : columnHeaders) {
             final String key = pColumnHeader.getColumnName();
             if (changedColumns.containsKey(key)) {
@@ -1588,7 +1636,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                                 + singleQuote;
                     }
                 }
-                sql += "`" + key + "` = " + pValueWrite;
+                sql += sqlGenerator.escape(key) + " = " + pValueWrite;
             }
         }
 
@@ -1783,7 +1831,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
                 }
                 paramValue = tmpBoolean.toString();
             } else if (columnHeader.isString()) {
-                if (paramValue.length() > columnHeader.getColumnLength()) {
+                if (columnHeader.getColumnLength() > 0 && paramValue.length() > columnHeader.getColumnLength()) {
                     final ApiParameterError error = ApiParameterError.parameterError(
                             "validation.msg.datatable.entry.column.exceeds.maxlength",
                             "The column `" + columnHeader.getColumnName() + "` exceeds its defined max-length ",
@@ -1801,13 +1849,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
 
     private String getDeleteEntriesSql(final String datatable, final String FKField, final Long appTableId) {
 
-        return "delete from `" + datatable + "` where `" + FKField + "` = " + appTableId;
+        return "delete from " + sqlGenerator.escape(datatable) + " where " + sqlGenerator.escape(FKField) + " = " + appTableId;
 
     }
 
     private String getDeleteEntrySql(final String datatable, final Long datatableId) {
 
-        return "delete from `" + datatable + "` where `id` = " + datatableId;
+        return "delete from " + sqlGenerator.escape(datatable) + " where id = " + datatableId;
 
     }
 
@@ -1841,17 +1889,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
     @Override
     public Long countDatatableEntries(final String datatableName, final Long appTableId, String foreignKeyColumn) {
 
-        final String sqlString = "SELECT COUNT(`" + foreignKeyColumn + "`) FROM `" + datatableName + "` WHERE `" + foreignKeyColumn + "`="
-                + appTableId;
+        final String sqlString = "SELECT COUNT(" + sqlGenerator.escape(foreignKeyColumn) + ") FROM " + sqlGenerator.escape(datatableName)
+                + " WHERE " + sqlGenerator.escape(foreignKeyColumn) + "=" + appTableId;
         final Long count = this.jdbcTemplate.queryForObject(sqlString, Long.class);
         return count;
     }
 
     public boolean isDatatableAttachedToEntityDatatableCheck(final String datatableName) {
         StringBuilder builder = new StringBuilder();
-        builder.append(" SELECT COUNT(edc.`x_registered_table_name`) FROM `x_registered_table` xrt ");
-        builder.append(" JOIN m_entity_datatable_check edc ON edc.`x_registered_table_name` = xrt.`registered_table_name`");
-        builder.append(" WHERE edc.`x_registered_table_name` = '" + datatableName + "'");
+        builder.append(" SELECT COUNT(edc.x_registered_table_name) FROM x_registered_table xrt ");
+        builder.append(" JOIN m_entity_datatable_check edc ON edc.x_registered_table_name = xrt.registered_table_name");
+        builder.append(" WHERE edc.x_registered_table_name = '" + datatableName + "'");
         final Long count = this.jdbcTemplate.queryForObject(builder.toString(), Long.class);
         return count > 0 ? true : false;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadServiceImpl.java
index a00f38a..6139cbe 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobRunnerReadServiceImpl.java
@@ -26,6 +26,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.jobs.data.JobDetailData;
 import org.apache.fineract.infrastructure.jobs.data.JobDetailHistoryData;
 import org.apache.fineract.infrastructure.jobs.exception.JobNotFoundException;
@@ -36,24 +37,30 @@ import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.RowMapper;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
+@Transactional(readOnly = true)
 public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerReadService {
 
     private final JdbcTemplate jdbcTemplate;
     private final ColumnValidator columnValidator;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
-    private final PaginationHelper<JobDetailHistoryData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
-    public SchedulerJobRunnerReadServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public SchedulerJobRunnerReadServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.columnValidator = columnValidator;
+        this.sqlGenerator = sqlGenerator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
     public List<JobDetailData> findAllJobDeatils() {
-        final JobDetailMapper detailMapper = new JobDetailMapper();
+        final JobDetailMapper detailMapper = new JobDetailMapper(sqlGenerator);
         final String sql = detailMapper.schema();
         final List<JobDetailData> JobDeatils = this.jdbcTemplate.query(sql, detailMapper, new Object[] {});
         return JobDeatils;
@@ -63,7 +70,7 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
     @Override
     public JobDetailData retrieveOne(final Long jobId) {
         try {
-            final JobDetailMapper detailMapper = new JobDetailMapper();
+            final JobDetailMapper detailMapper = new JobDetailMapper(sqlGenerator);
             final String sql = detailMapper.schema() + " where job.id=?";
             return this.jdbcTemplate.queryForObject(sql, detailMapper, new Object[] { jobId });
         } catch (final EmptyResultDataAccessException e) {
@@ -76,9 +83,9 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
         if (!isJobExist(jobId)) {
             throw new JobNotFoundException(String.valueOf(jobId));
         }
-        final JobHistoryMapper jobHistoryMapper = new JobHistoryMapper();
+        final JobHistoryMapper jobHistoryMapper = new JobHistoryMapper(sqlGenerator);
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(jobHistoryMapper.schema());
         sqlBuilder.append(" where job.id=?");
         if (searchParameters.isOrderByRequested()) {
@@ -91,15 +98,15 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { jobId },
-                jobHistoryMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), new Object[] { jobId }, jobHistoryMapper);
     }
 
     @Override
@@ -131,10 +138,16 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
 
     private static final class JobDetailMapper implements RowMapper<JobDetailData> {
 
-        private final StringBuilder sqlBuilder = new StringBuilder("select").append(
-                " job.id,job.display_name as displayName,job.next_run_time as nextRunTime,job.initializing_errorlog as initializingError,job.cron_expression as cronExpression,job.is_active as active,job.currently_running as currentlyRunning,")
-                .append(" runHistory.version,runHistory.start_time as lastRunStartTime,runHistory.end_time as lastRunEndTime,runHistory.`status`,runHistory.error_message as jobRunErrorMessage,runHistory.trigger_type as triggerType,runHistory.error_log as jobRunErrorLog ")
-                .append(" from job job  left join job_run_history runHistory ON job.id=runHistory.job_id and job.previous_run_start_time=runHistory.start_time ");
+        private final StringBuilder sqlBuilder;
+
+        JobDetailMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            sqlBuilder = new StringBuilder("select").append(
+                    " job.id,job.display_name as displayName,job.next_run_time as nextRunTime,job.initializing_errorlog as initializingError,job.cron_expression as cronExpression,job.is_active as active,job.currently_running as currentlyRunning,")
+                    .append(" runHistory.version,runHistory.start_time as lastRunStartTime,runHistory.end_time as lastRunEndTime,runHistory."
+                            + sqlGenerator.escape("status")
+                            + ",runHistory.error_message as jobRunErrorMessage,runHistory.trigger_type as triggerType,runHistory.error_log as jobRunErrorLog ")
+                    .append(" from job job  left join job_run_history runHistory ON job.id=runHistory.job_id and job.previous_run_start_time=runHistory.start_time ");
+        }
 
         public String schema() {
             return this.sqlBuilder.toString();
@@ -172,9 +185,15 @@ public class SchedulerJobRunnerReadServiceImpl implements SchedulerJobRunnerRead
 
     private static final class JobHistoryMapper implements RowMapper<JobDetailHistoryData> {
 
-        private final StringBuilder sqlBuilder = new StringBuilder(200).append(
-                " runHistory.version,runHistory.start_time as runStartTime,runHistory.end_time as runEndTime,runHistory.`status`,runHistory.error_message as jobRunErrorMessage,runHistory.trigger_type as triggerType,runHistory.error_log as jobRunErrorLog ")
-                .append(" from job job join job_run_history runHistory ON job.id=runHistory.job_id");
+        private final StringBuilder sqlBuilder;
+
+        JobHistoryMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            sqlBuilder = new StringBuilder(200)
+                    .append(" runHistory.version,runHistory.start_time as runStartTime,runHistory.end_time as runEndTime,runHistory."
+                            + sqlGenerator.escape("status")
+                            + ",runHistory.error_message as jobRunErrorMessage,runHistory.trigger_type as triggerType,runHistory.error_log as jobRunErrorLog ")
+                    .append(" from job job join job_run_history runHistory ON job.id=runHistory.job_id");
+        }
 
         public String schema() {
             return this.sqlBuilder.toString();
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/openjpa/OpenJpaTransactionManager.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/openjpa/OpenJpaTransactionManager.java
new file mode 100644
index 0000000..ae9b83d
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/openjpa/OpenJpaTransactionManager.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.openjpa;
+
+import javax.persistence.EntityManager;
+import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport;
+import org.springframework.orm.jpa.EntityManagerHolder;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.transaction.support.DefaultTransactionStatus;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+public class OpenJpaTransactionManager extends JpaTransactionManager {
+
+    @Override
+    protected void doCommit(DefaultTransactionStatus status) {
+        JdbcTransactionObjectSupport txObject = (JdbcTransactionObjectSupport) status.getTransaction();
+        if (txObject.isReadOnly()) {
+            EntityManagerHolder holder = (EntityManagerHolder) TransactionSynchronizationManager.getResource(obtainEntityManagerFactory());
+            if (holder != null) {
+                EntityManager entityManager = holder.getEntityManager();
+                entityManager.clear();
+            }
+        }
+        super.doCommit(status);
+    }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobReadPlatformServiceImpl.java
index f09f576..518c610 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobReadPlatformServiceImpl.java
@@ -31,6 +31,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.dataqueries.data.ReportData;
 import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobData;
 import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobEmailAttachmentFileFormat;
@@ -49,11 +50,16 @@ public class ReportMailingJobReadPlatformServiceImpl implements ReportMailingJob
 
     private final JdbcTemplate jdbcTemplate;
     private final ColumnValidator columnValidator;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
+    private final PaginationHelper paginationHelper;
 
     @Autowired
-    public ReportMailingJobReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public ReportMailingJobReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.columnValidator = columnValidator;
+        this.sqlGenerator = sqlGenerator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -61,9 +67,8 @@ public class ReportMailingJobReadPlatformServiceImpl implements ReportMailingJob
         final StringBuilder sqlStringBuilder = new StringBuilder(200);
         final List<Object> queryParameters = new ArrayList<>();
         final ReportMailingJobMapper mapper = new ReportMailingJobMapper();
-        final PaginationHelper<ReportMailingJobData> paginationHelper = new PaginationHelper<>();
 
-        sqlStringBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlStringBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlStringBuilder.append(mapper.reportMailingJobSchema());
         sqlStringBuilder.append(" where rmj.is_deleted = false");
 
@@ -79,15 +84,15 @@ public class ReportMailingJobReadPlatformServiceImpl implements ReportMailingJob
         }
 
         if (searchParameters.isLimited()) {
-            sqlStringBuilder.append(" limit ").append(searchParameters.getLimit());
-
+            sqlStringBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlStringBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlStringBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlStringBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        return paginationHelper.fetchPage(this.jdbcTemplate, "SELECT FOUND_ROWS()", sqlStringBuilder.toString(), queryParameters.toArray(),
-                mapper);
+        return paginationHelper.fetchPage(this.jdbcTemplate, sqlStringBuilder.toString(), queryParameters.toArray(), mapper);
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobRunHistoryReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobRunHistoryReadPlatformServiceImpl.java
index 5c83caf..9f5c65e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobRunHistoryReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/service/ReportMailingJobRunHistoryReadPlatformServiceImpl.java
@@ -28,6 +28,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.reportmailingjob.data.ReportMailingJobRunHistoryData;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -39,15 +40,19 @@ import org.springframework.stereotype.Service;
 public class ReportMailingJobRunHistoryReadPlatformServiceImpl implements ReportMailingJobRunHistoryReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final ReportMailingJobRunHistoryMapper reportMailingJobRunHistoryMapper;
     private final ColumnValidator columnValidator;
-    private final PaginationHelper<ReportMailingJobRunHistoryData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
-    public ReportMailingJobRunHistoryReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public ReportMailingJobRunHistoryReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
         this.reportMailingJobRunHistoryMapper = new ReportMailingJobRunHistoryMapper();
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -56,7 +61,7 @@ public class ReportMailingJobRunHistoryReadPlatformServiceImpl implements Report
         final StringBuilder sqlStringBuilder = new StringBuilder(200);
         final List<Object> queryParameters = new ArrayList<>();
 
-        sqlStringBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlStringBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlStringBuilder.append(this.reportMailingJobRunHistoryMapper.reportMailingJobRunHistorySchema());
 
         if (reportMailingJobId != null) {
@@ -74,15 +79,16 @@ public class ReportMailingJobRunHistoryReadPlatformServiceImpl implements Report
         }
 
         if (searchParameters.isLimited()) {
-            sqlStringBuilder.append(" limit ").append(searchParameters.getLimit());
-
+            sqlStringBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlStringBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlStringBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlStringBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, "SELECT FOUND_ROWS()", sqlStringBuilder.toString(),
-                queryParameters.toArray(), this.reportMailingJobRunHistoryMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlStringBuilder.toString(), queryParameters.toArray(),
+                this.reportMailingJobRunHistoryMapper);
     }
 
     private static final class ReportMailingJobRunHistoryMapper implements RowMapper<ReportMailingJobRunHistoryData> {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/service/SmsReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/service/SmsReadPlatformServiceImpl.java
index 9593ec7..a860fa0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/service/SmsReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/service/SmsReadPlatformServiceImpl.java
@@ -32,6 +32,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.infrastructure.sms.data.SmsData;
 import org.apache.fineract.infrastructure.sms.domain.SmsMessageEnumerations;
@@ -47,15 +48,19 @@ import org.springframework.stereotype.Service;
 public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final SmsMapper smsRowMapper;
-    private final PaginationHelper<SmsData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
     private final ColumnValidator columnValidator;
 
     @Autowired
-    public SmsReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public SmsReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
         this.smsRowMapper = new SmsMapper();
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
     }
 
     private static final class SmsMapper implements RowMapper<SmsData> {
@@ -130,7 +135,7 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     @Override
     public Collection<SmsData> retrieveAllPending(final Long campaignId, final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         String sql = "select " + this.smsRowMapper.schema() + " where smo.status_enum = " + SmsMessageStatusType.PENDING.getValue();
         if (campaignId != null) {
             sql += " and smo.campaign_id = " + campaignId;
@@ -143,7 +148,7 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     @Override
     public Collection<SmsData> retrieveAllSent(final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select " + this.smsRowMapper.schema() + " where smo.status_enum IN ("
                 + SmsMessageStatusType.WAITING_FOR_DELIVERY_REPORT.getValue() + "," + SmsMessageStatusType.SENT.getValue() + ")"
                 + sqlPlusLimit;
@@ -153,7 +158,7 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     @Override
     public List<Long> retrieveExternalIdsOfAllSent(final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select external_id from " + this.smsRowMapper.tableName() + " where status_enum = "
                 + SmsMessageStatusType.SENT.getValue() + sqlPlusLimit;
 
@@ -162,18 +167,17 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     @Override
     public Page<Long> retrieveAllWaitingForDeliveryReport(final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select id from " + this.smsRowMapper.tableName() + " where status_enum = "
                 + SmsMessageStatusType.WAITING_FOR_DELIVERY_REPORT.getValue() + sqlPlusLimit;
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(jdbcTemplate, sql, sqlCountRows, Long.class);
+        return this.paginationHelper.fetchPage(jdbcTemplate, sql, Long.class);
         // (this.jdbcTemplate, sqlCountRows, new Object [] {}, Long.class);
         // this.jdbcTemplate.queryForList(sql, Long.class);
     }
 
     @Override
     public List<Long> retrieveAllPending(final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select external_id from " + this.smsRowMapper.tableName() + " where status_enum = "
                 + SmsMessageStatusType.PENDING.getValue() + sqlPlusLimit;
 
@@ -182,7 +186,7 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     @Override
     public Collection<SmsData> retrieveAllDelivered(final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select " + this.smsRowMapper.schema() + " where smo.status_enum = " + SmsMessageStatusType.DELIVERED.getValue()
                 + sqlPlusLimit;
 
@@ -191,7 +195,7 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
 
     @Override
     public Collection<SmsData> retrieveAllFailed(final Integer limit) {
-        final String sqlPlusLimit = limit > 0 ? " limit 0, " + limit : "";
+        final String sqlPlusLimit = limit > 0 ? " " + sqlGenerator.limit(limit) : "";
         final String sql = "select " + this.smsRowMapper.schema() + " where smo.status_enum = " + SmsMessageStatusType.FAILED.getValue()
                 + sqlPlusLimit;
 
@@ -204,7 +208,7 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
         final StringBuilder sqlBuilder = new StringBuilder(200);
         final Object[] objectArray = new Object[10];
         int arrayPos = 0;
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.smsRowMapper.schema());
         if (status != null) {
             sqlBuilder.append(" where smo.campaign_id = ? and smo.status_enum= ? ");
@@ -239,14 +243,15 @@ public class SmsReadPlatformServiceImpl implements SmsReadPlatformService {
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray, this.smsRowMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.smsRowMapper);
     }
 
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
index 055dfe1..c2f6984 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/interoperation/service/InteropServiceImpl.java
@@ -50,6 +50,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityEx
 import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.interoperation.data.InteropAccountData;
 import org.apache.fineract.interoperation.data.InteropIdentifierAccountResponseData;
@@ -141,6 +142,7 @@ public class InteropServiceImpl implements InteropService {
     private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
 
     private final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public InteropServiceImpl(PlatformSecurityContext securityContext, InteropDataValidator interopDataValidator,
@@ -150,7 +152,7 @@ public class InteropServiceImpl implements InteropService {
             SavingsHelper savingsHelper, SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
             SavingsAccountDomainService savingsAccountService, final RoutingDataSource dataSource,
             final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
-            final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer) {
+            final DefaultToApiJsonSerializer<LoanAccountData> toApiJsonSerializer, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.securityContext = securityContext;
         this.dataValidator = interopDataValidator;
         this.savingsAccountRepository = savingsAccountRepository;
@@ -166,13 +168,20 @@ public class InteropServiceImpl implements InteropService {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
         this.toApiJsonSerializer = toApiJsonSerializer;
+        this.sqlGenerator = sqlGenerator;
     }
 
     private static final class KycMapper implements RowMapper<InteropKycData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        KycMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String schema() {
             return " country.code_value as nationality, c.date_of_birth as dateOfBirth, c.mobile_no as contactPhone, gender.code_value as gender, c.email_address as email, "
-                    + "kyc.code_value as idType, ci.document_key as idNo, ci.`description` as description, "
+                    + "kyc.code_value as idType, ci.document_key as idNo, ci." + sqlGenerator.escape("description") + " as description, "
                     + "country.code_value as country, a.`address_line_1`, a.`address_line_2`, "
                     + "a.city, state.code_value as stateProvince, a.postal_code as postalCode, c.firstname as firstName, c.middlename as middleName,"
                     + "c.lastname as lastName, c.display_name as displayName" + " from " + "m_client c "
@@ -512,7 +521,7 @@ public class InteropServiceImpl implements InteropService {
         Long client_id = savingsAccount.getClient().getId();
 
         try {
-            final InteropServiceImpl.KycMapper rm = new InteropServiceImpl.KycMapper();
+            final InteropServiceImpl.KycMapper rm = new InteropServiceImpl.KycMapper(sqlGenerator);
             final String sql = "select " + rm.schema() + " where c.id = ?";
 
             final InteropKycData accountKyc = this.jdbcTemplate.queryForObject(sql, rm, new Object[] { client_id });
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java
index d1fb312..2d8ad9a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/NotificationReadPlatformServiceImpl.java
@@ -27,6 +27,7 @@ import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.notification.cache.CacheNotificationResponseHeader;
@@ -43,17 +44,20 @@ public class NotificationReadPlatformServiceImpl implements NotificationReadPlat
     private final JdbcTemplate jdbcTemplate;
     private final PlatformSecurityContext context;
     private final ColumnValidator columnValidator;
-    private final PaginationHelper<NotificationData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final NotificationDataRow notificationDataRow = new NotificationDataRow();
     private final NotificationMapperRow notificationMapperRow = new NotificationMapperRow();
     private HashMap<Long, HashMap<Long, CacheNotificationResponseHeader>> tenantNotificationResponseHeaderCache = new HashMap<>();
 
     @Autowired
     public NotificationReadPlatformServiceImpl(final RoutingDataSource dataSource, final PlatformSecurityContext context,
-            final ColumnValidator columnValidator) {
+            final ColumnValidator columnValidator, DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.context = context;
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -114,8 +118,9 @@ public class NotificationReadPlatformServiceImpl implements NotificationReadPlat
     @Override
     public Page<NotificationData> getAllUnreadNotifications(final SearchParameters searchParameters) {
         final Long appUserId = context.authenticatedUser().getId();
-        String sql = "SELECT SQL_CALC_FOUND_ROWS ng.id as id, nm.user_id as userId, ng.object_type as objectType, "
-                + "ng.object_identifier as objectId, ng.actor as actor, ng.action action, ng.notification_content "
+        String sql = "SELECT " + sqlGenerator.calcFoundRows() + " ng.id as id, nm.user_id as userId, ng.object_type as objectType, "
+                + "ng.object_identifier as objectId, ng.actor as actor, ng." + sqlGenerator.escape("action")
+                + " as action, ng.notification_content "
                 + "as content, ng.is_system_generated as isSystemGenerated, nm.created_at as createdAt "
                 + "FROM notification_mapper nm INNER JOIN notification_generator ng ON nm.notification_id = ng.id "
                 + "WHERE nm.user_id = ? AND nm.is_read = false order by nm.created_at desc";
@@ -126,8 +131,9 @@ public class NotificationReadPlatformServiceImpl implements NotificationReadPlat
     @Override
     public Page<NotificationData> getAllNotifications(SearchParameters searchParameters) {
         final Long appUserId = context.authenticatedUser().getId();
-        String sql = "SELECT SQL_CALC_FOUND_ROWS ng.id as id, nm.user_id as userId, ng.object_type as objectType, "
-                + "ng.object_identifier as objectId, ng.actor as actor, ng.action action, ng.notification_content "
+        String sql = "SELECT " + sqlGenerator.calcFoundRows() + " ng.id as id, nm.user_id as userId, ng.object_type as objectType, "
+                + "ng.object_identifier as objectId, ng.actor as actor, ng." + sqlGenerator.escape("action")
+                + " as action, ng.notification_content "
                 + "as content, ng.is_system_generated as isSystemGenerated, nm.created_at as createdAt "
                 + "FROM notification_mapper nm INNER JOIN notification_generator ng ON nm.notification_id = ng.id "
                 + "WHERE nm.user_id = ? order by nm.created_at desc";
@@ -149,15 +155,16 @@ public class NotificationReadPlatformServiceImpl implements NotificationReadPlat
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] params = new Object[] { appUserId };
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), params, this.notificationDataRow);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), params, this.notificationDataRow);
     }
 
     private static final class NotificationMapperRow implements RowMapper<NotificationMapperData> {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java
index 31dc35e..7122bcf 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/notification/service/TopicDomainServiceImpl.java
@@ -35,9 +35,11 @@ import org.apache.fineract.useradministration.domain.RoleRepository;
 import org.apache.fineract.useradministration.exception.RoleNotFoundException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
 
 @Service
+@Transactional
 public class TopicDomainServiceImpl implements TopicDomainService {
 
     private final RoleRepository roleRepository;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
index 302fc41..ef9c099 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeReadPlatformServiceImpl.java
@@ -28,6 +28,7 @@ import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
@@ -47,6 +48,7 @@ import org.springframework.stereotype.Service;
 public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PlatformSecurityContext context;
     private final CurrencyReadPlatformService currencyReadPlatformService;
     private final ColumnValidator columnValidator;
@@ -55,11 +57,12 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
     @Autowired
     public OfficeReadPlatformServiceImpl(final PlatformSecurityContext context,
             final CurrencyReadPlatformService currencyReadPlatformService, final RoutingDataSource dataSource,
-            final ColumnValidator columnValidator) {
+            final ColumnValidator columnValidator, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.currencyReadPlatformService = currencyReadPlatformService;
         this.columnValidator = columnValidator;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
     }
 
     private static final class OfficeMapper implements RowMapper<OfficeData> {
@@ -105,13 +108,20 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
 
     private static final class OfficeTransactionMapper implements RowMapper<OfficeTransactionData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        OfficeTransactionMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String schema() {
             return " ot.id as id, ot.transaction_date as transactionDate, ot.from_office_id as fromOfficeId, fromoff.name as fromOfficeName, "
                     + " ot.to_office_id as toOfficeId, tooff.name as toOfficeName, ot.transaction_amount as transactionAmount, ot.description as description, "
                     + " ot.currency_code as currencyCode, rc.decimal_places as currencyDigits, rc.currency_multiplesof as inMultiplesOf, "
                     + " rc.name as currencyName, rc.internationalized_name_code as currencyNameCode, rc.display_symbol as currencyDisplaySymbol "
                     + " from m_office_transaction ot " + " left join m_office fromoff on fromoff.id = ot.from_office_id "
-                    + " left join m_office tooff on tooff.id = ot.to_office_id " + " join m_currency rc on rc.`code` = ot.currency_code";
+                    + " left join m_office tooff on tooff.id = ot.to_office_id " + " join m_currency rc on rc."
+                    + sqlGenerator.escape("code") + " = ot.currency_code";
         }
 
         @Override
@@ -244,7 +254,7 @@ public class OfficeReadPlatformServiceImpl implements OfficeReadPlatformService
         final String hierarchy = currentUser.getOffice().getHierarchy();
         final String hierarchySearchString = hierarchy + "%";
 
-        final OfficeTransactionMapper rm = new OfficeTransactionMapper();
+        final OfficeTransactionMapper rm = new OfficeTransactionMapper(sqlGenerator);
         final String sql = "select " + rm.schema()
                 + " where (fromoff.hierarchy like ? or tooff.hierarchy like ?) order by ot.transaction_date, ot.id";
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java
index 46e1ccb..cd04c17 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerManagementReadPlatformServiceImpl.java
@@ -33,6 +33,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
@@ -70,19 +71,23 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
     private final OfficeReadPlatformService officeReadPlatformService;
     private final StaffReadPlatformService staffReadPlatformService;
     private final CurrencyReadPlatformService currencyReadPlatformService;
-    private final PaginationHelper<CashierTransactionData> paginationHelper = new PaginationHelper<>();
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
+    private final PaginationHelper paginationHelper;
     private final ColumnValidator columnValidator;
 
     @Autowired
     public TellerManagementReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
             final OfficeReadPlatformService officeReadPlatformService, StaffReadPlatformService staffReadPlatformService,
-            final CurrencyReadPlatformService currencyReadPlatformService, final ColumnValidator columnValidator) {
+            final CurrencyReadPlatformService currencyReadPlatformService, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.officeReadPlatformService = officeReadPlatformService;
         this.staffReadPlatformService = staffReadPlatformService;
         this.currencyReadPlatformService = currencyReadPlatformService;
         this.columnValidator = columnValidator;
+        this.sqlGenerator = sqlGenerator;
+        this.paginationHelper = paginationHelper;
     }
 
     private static final class TellerMapper implements RowMapper<TellerData> {
@@ -545,12 +550,13 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
                 + " and (cli_txn.payment_detail_id IS NULL OR payType.is_cash_payment = true) ) " + " order by created_date ";
 
         if (searchParameters.isLimited()) {
-            sql = sql + " limit " + searchParameters.getLimit();
+            sql += " ";
             if (searchParameters.isOffset()) {
-                sql = sql + " offset " + searchParameters.getOffset();
+                sql += sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset());
+            } else {
+                sql += sqlGenerator.limit(searchParameters.getLimit());
             }
         }
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         // return this.jdbcTemplate.query(sql, ctm, new Object[] { cashierId,
         // currencyCode, hierarchySearchString, cashierId, currencyCode,
         // hierarchySearchString, cashierId, currencyCode,
@@ -558,7 +564,7 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
         // });
         Object[] params = new Object[] { cashierId, currencyCode, hierarchySearchString, cashierId, currencyCode, hierarchySearchString,
                 cashierId, currencyCode, hierarchySearchString, cashierId, currencyCode, hierarchySearchString };
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sql, params, ctm);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sql, params, ctm);
     }
 
     private static final class CashierMapper implements RowMapper<CashierData> {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java
index 343c91d..73686e3 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/AccountTransfersReadPlatformServiceImpl.java
@@ -35,6 +35,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.office.data.OfficeData;
@@ -62,25 +63,28 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
     private final OfficeReadPlatformService officeReadPlatformService;
     private final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService;
     private final ColumnValidator columnValidator;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     // mapper
     private final AccountTransfersMapper accountTransfersMapper;
 
     // pagination
-    private final PaginationHelper<AccountTransferData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
     private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
     @Autowired
     public AccountTransfersReadPlatformServiceImpl(final RoutingDataSource dataSource,
             final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
-            final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService, final ColumnValidator columnValidator) {
+            final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.clientReadPlatformService = clientReadPlatformService;
         this.officeReadPlatformService = officeReadPlatformService;
         this.portfolioAccountReadPlatformService = portfolioAccountReadPlatformService;
         this.columnValidator = columnValidator;
-
+        this.sqlGenerator = sqlGenerator;
         this.accountTransfersMapper = new AccountTransfersMapper();
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -215,7 +219,7 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
     public Page<AccountTransferData> retrieveAll(final SearchParameters searchParameters, final Long accountDetailId) {
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.accountTransfersMapper.schema());
         Object[] finalObjectArray = {};
         if (accountDetailId != null) {
@@ -239,9 +243,7 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
-                this.accountTransfersMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.accountTransfersMapper);
     }
 
     @Override
@@ -411,7 +413,7 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
     public Page<AccountTransferData> retrieveByStandingInstruction(final Long id, final SearchParameters searchParameters) {
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.accountTransfersMapper.schema()).append(
                 " join m_account_transfer_standing_instructions atsi on atsi.account_transfer_details_id = att.account_transfer_details_id ");
         sqlBuilder.append(" where atsi.id = ?");
@@ -427,17 +429,17 @@ public class AccountTransfersReadPlatformServiceImpl implements AccountTransfers
             }
 
             if (searchParameters.isLimited()) {
-                sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+                sqlBuilder.append(" ");
                 if (searchParameters.isOffset()) {
-                    sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+                } else {
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
                 }
             }
         }
 
         final Object[] finalObjectArray = { id };
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
-                this.accountTransfersMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.accountTransfersMapper);
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java
index 28ccc9a..8e49c0e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/PortfolioAccountReadPlatformServiceImpl.java
@@ -26,6 +26,7 @@ import java.util.Collection;
 import java.util.List;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.account.PortfolioAccountType;
 import org.apache.fineract.portfolio.account.data.PortfolioAccountDTO;
@@ -48,11 +49,11 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
     private final PortfolioLoanAccountRefundByTransferMapper accountRefundByTransferMapper;
 
     @Autowired
-    public PortfolioAccountReadPlatformServiceImpl(final RoutingDataSource dataSource) {
+    public PortfolioAccountReadPlatformServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.savingsAccountMapper = new PortfolioSavingsAccountMapper();
         this.loanAccountMapper = new PortfolioLoanAccountMapper();
-        this.accountRefundByTransferMapper = new PortfolioLoanAccountRefundByTransferMapper();
+        this.accountRefundByTransferMapper = new PortfolioLoanAccountRefundByTransferMapper(sqlGenerator);
     }
 
     @Override
@@ -295,7 +296,7 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
 
         private final String schemaSql;
 
-        PortfolioLoanAccountRefundByTransferMapper() {
+        PortfolioLoanAccountRefundByTransferMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
 
             final StringBuilder amountQueryString = new StringBuilder(400);
             amountQueryString.append("(select (SUM(COALESCE(mr.principal_completed_derived, 0)) +");
@@ -304,7 +305,7 @@ public class PortfolioAccountReadPlatformServiceImpl implements PortfolioAccount
             amountQueryString.append(" SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived");
             amountQueryString.append(" from m_loan ml INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id");
             amountQueryString.append(" where ml.id=? and ml.loan_status_id = 300");
-            amountQueryString.append("  and  mr.duedate >= CURDATE() group by ml.id having");
+            amountQueryString.append("  and  mr.duedate >= " + sqlGenerator.currentDate() + " group by ml.id having");
             amountQueryString.append(" (SUM(COALESCE(mr.principal_completed_derived, 0)) + ");
             amountQueryString.append(" SUM(COALESCE(mr.interest_completed_derived, 0)) + ");
             amountQueryString.append("SUM(COALESCE(mr.fee_charges_completed_derived, 0)) + ");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java
index ecaa85f..659f591 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionHistoryReadPlatformServiceImpl.java
@@ -34,6 +34,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.organisation.office.data.OfficeData;
 import org.apache.fineract.portfolio.account.PortfolioAccountType;
@@ -50,26 +51,30 @@ import org.springframework.stereotype.Service;
 public class StandingInstructionHistoryReadPlatformServiceImpl implements StandingInstructionHistoryReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final ColumnValidator columnValidator;
 
     // mapper
     private final StandingInstructionHistoryMapper standingInstructionHistoryMapper;
 
     // pagination
-    private final PaginationHelper<StandingInstructionHistoryData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
-    public StandingInstructionHistoryReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public StandingInstructionHistoryReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
         this.standingInstructionHistoryMapper = new StandingInstructionHistoryMapper();
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
     public Page<StandingInstructionHistoryData> retrieveAll(StandingInstructionDTO standingInstructionDTO) {
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.standingInstructionHistoryMapper.schema());
         if (standingInstructionDTO.transferType() != null || standingInstructionDTO.clientId() != null
                 || standingInstructionDTO.clientName() != null
@@ -149,15 +154,16 @@ public class StandingInstructionHistoryReadPlatformServiceImpl implements Standi
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
         final Object[] finalObjectArray = paramObj.toArray();
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray,
                 this.standingInstructionHistoryMapper);
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java
index 198ec7a..66b0525 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionReadPlatformServiceImpl.java
@@ -41,6 +41,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.organisation.office.data.OfficeData;
 import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
@@ -76,25 +77,29 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
     private final OfficeReadPlatformService officeReadPlatformService;
     private final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService;
     private final DropdownReadPlatformService dropdownReadPlatformService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     // mapper
     private final StandingInstructionMapper standingInstructionMapper;
 
     // pagination
-    private final PaginationHelper<StandingInstructionData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     @Autowired
     public StandingInstructionReadPlatformServiceImpl(final RoutingDataSource dataSource,
             final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
             final PortfolioAccountReadPlatformService portfolioAccountReadPlatformService,
-            final DropdownReadPlatformService dropdownReadPlatformService, final ColumnValidator columnValidator) {
+            final DropdownReadPlatformService dropdownReadPlatformService, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.clientReadPlatformService = clientReadPlatformService;
         this.officeReadPlatformService = officeReadPlatformService;
         this.portfolioAccountReadPlatformService = portfolioAccountReadPlatformService;
         this.dropdownReadPlatformService = dropdownReadPlatformService;
+        this.sqlGenerator = sqlGenerator;
         this.standingInstructionMapper = new StandingInstructionMapper();
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -257,7 +262,7 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
     public Page<StandingInstructionData> retrieveAll(final StandingInstructionDTO standingInstructionDTO) {
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.standingInstructionMapper.schema());
         if (standingInstructionDTO.transferType() != null || standingInstructionDTO.clientId() != null
                 || standingInstructionDTO.clientName() != null) {
@@ -315,16 +320,16 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
         final Object[] finalObjectArray = paramObj.toArray();
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
-                this.standingInstructionMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.standingInstructionMapper);
     }
 
     @Override
@@ -332,9 +337,10 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
         final StringBuilder sqlBuilder = new StringBuilder(200);
         sqlBuilder.append("select ");
         sqlBuilder.append(this.standingInstructionMapper.schema());
-        sqlBuilder.append(
-                " where atsi.status=? and CURRENT_DATE() >= atsi.valid_from and (atsi.valid_till IS NULL or CURRENT_DATE() < atsi.valid_till) ")
-                .append(" and  (atsi.last_run_date <> CURRENT_DATE() or atsi.last_run_date IS NULL)")
+        sqlBuilder
+                .append(" where atsi.status=? and " + sqlGenerator.currentDate() + " >= atsi.valid_from and (atsi.valid_till IS NULL or "
+                        + sqlGenerator.currentDate() + " < atsi.valid_till) ")
+                .append(" and  (atsi.last_run_date <> " + sqlGenerator.currentDate() + " or atsi.last_run_date IS NULL)")
                 .append(" ORDER BY atsi.priority DESC");
         return this.jdbcTemplate.query(sqlBuilder.toString(), this.standingInstructionMapper, status);
     }
@@ -354,7 +360,8 @@ public class StandingInstructionReadPlatformServiceImpl implements StandingInstr
     @Override
     public StandingInstructionDuesData retriveLoanDuesData(final Long loanId) {
         final StandingInstructionLoanDuesMapper rm = new StandingInstructionLoanDuesMapper();
-        final String sql = "select " + rm.schema() + " where ml.id= ? and ls.duedate <= CURRENT_DATE() and ls.completed_derived <> 1";
+        final String sql = "select " + rm.schema() + " where ml.id= ? and ls.duedate <= " + sqlGenerator.currentDate()
+                + " and ls.completed_derived <> 1";
         return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId });
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java
index 16919cf..89c392f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java
@@ -40,6 +40,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
 import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
 import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
@@ -85,6 +86,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
     private final StandingInstructionReadPlatformService standingInstructionReadPlatformService;
     private final AccountTransfersWritePlatformService accountTransfersWritePlatformService;
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public StandingInstructionWritePlatformServiceImpl(final StandingInstructionDataValidator standingInstructionDataValidator,
@@ -92,7 +94,8 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
             final AccountTransferDetailRepository accountTransferDetailRepository,
             final StandingInstructionRepository standingInstructionRepository,
             final StandingInstructionReadPlatformService standingInstructionReadPlatformService,
-            final AccountTransfersWritePlatformService accountTransfersWritePlatformService, final RoutingDataSource dataSource) {
+            final AccountTransfersWritePlatformService accountTransfersWritePlatformService, final RoutingDataSource dataSource,
+            DatabaseSpecificSQLGenerator sqlGenerator) {
         this.standingInstructionDataValidator = standingInstructionDataValidator;
         this.standingInstructionAssembler = standingInstructionAssembler;
         this.accountTransferDetailRepository = accountTransferDetailRepository;
@@ -100,6 +103,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
         this.standingInstructionReadPlatformService = standingInstructionReadPlatformService;
         this.accountTransfersWritePlatformService = accountTransfersWritePlatformService;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Transactional
@@ -261,7 +265,8 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
         boolean transferCompleted = true;
         StringBuilder errorLog = new StringBuilder();
         StringBuilder updateQuery = new StringBuilder(
-                "INSERT INTO m_account_transfer_standing_instructions_history (standing_instruction_id, `status`, amount,execution_time, error_log) VALUES (");
+                "INSERT INTO m_account_transfer_standing_instructions_history (standing_instruction_id, " + sqlGenerator.escape("status")
+                        + ", amount,execution_time, error_log) VALUES (");
         try {
             this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
         } catch (final PlatformApiDataValidationException e) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientFamilyMembers.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientFamilyMembers.java
index 5240160..5c18cd2 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientFamilyMembers.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientFamilyMembers.java
@@ -41,10 +41,10 @@ public class ClientFamilyMembers extends AbstractPersistableCustom {
     @Column(name = "firstname")
     private String firstName;
 
-    @Column(name = "middleName")
+    @Column(name = "middlename")
     private String middleName;
 
-    @Column(name = "lastName")
+    @Column(name = "lastname")
     private String lastName;
 
     @Column(name = "qualification")
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeReadPlatformServiceImpl.java
index abd069a..ecb8bf1 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeReadPlatformServiceImpl.java
@@ -29,6 +29,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.charge.data.ChargeData;
@@ -45,16 +46,20 @@ import org.springframework.stereotype.Service;
 @Service
 public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlatformService {
 
-    private final PaginationHelper<ClientChargeData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PlatformSecurityContext context;
     private final ClientChargeMapper clientChargeMapper;
 
     @Autowired
-    public ClientChargeReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
+    public ClientChargeReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
         this.clientChargeMapper = new ClientChargeMapper();
+        this.paginationHelper = paginationHelper;
     }
 
     public static final class ClientChargeMapper implements RowMapper<ClientChargeData> {
@@ -135,7 +140,7 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
             SearchParameters searchParameters) {
         final ClientChargeMapper rm = new ClientChargeMapper();
         final StringBuilder sqlBuilder = new StringBuilder();
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(rm.schema()).append(" where cc.client_id=? ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ").append(rm.schema()).append(" where cc.client_id=? ");
 
         // filter for active charges
         if (status.equalsIgnoreCase(ClientApiConstants.CLIENT_CHARGE_QUERY_PARAM_STATUS_VALUE_ACTIVE)) {
@@ -156,14 +161,15 @@ public class ClientChargeReadPlatformServiceImpl implements ClientChargeReadPlat
         // apply limit and offsets
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] { clientId },
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), new Object[] { clientId },
                 this.clientChargeMapper);
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java
index 9d58c26..ea2a15b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientReadPlatformServiceImpl.java
@@ -43,6 +43,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
 import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
 import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
@@ -88,7 +89,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
     private final CodeValueReadPlatformService codeValueReadPlatformService;
     private final SavingsProductReadPlatformService savingsProductReadPlatformService;
     // data mappers
-    private final PaginationHelper<ClientData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final ClientMapper clientMapper = new ClientMapper();
     private final ClientLookupMapper lookupMapper = new ClientLookupMapper();
     private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper();
@@ -110,7 +112,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
             final ClientFamilyMembersReadPlatformService clientFamilyMembersReadPlatformService,
             final ConfigurationReadPlatformService configurationReadPlatformService,
             final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator,
-            final ClientCollateralManagementRepositoryWrapper clientCollateralManagementRepositoryWrapper) {
+            final ClientCollateralManagementRepositoryWrapper clientCollateralManagementRepositoryWrapper,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.officeReadPlatformService = officeReadPlatformService;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
@@ -123,6 +126,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
         this.entityDatatableChecksReadService = entityDatatableChecksReadService;
         this.columnValidator = columnValidator;
         this.clientCollateralManagementRepositoryWrapper = clientCollateralManagementRepositoryWrapper;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -208,7 +213,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
         // }
         List<Object> paramList = new ArrayList<>(Arrays.asList(underHierarchySearchString, underHierarchySearchString));
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.clientMapper.schema());
         sqlBuilder.append(" where (o.hierarchy like ? or transferToOffice.hierarchy like ?) ");
 
@@ -235,15 +240,15 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
             }
 
             if (searchParameters.isLimited()) {
-                sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+                sqlBuilder.append(" ");
                 if (searchParameters.isOffset()) {
-                    sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+                } else {
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
                 }
             }
         }
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), paramList.toArray(),
-                this.clientMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), paramList.toArray(), this.clientMapper);
     }
 
     private String buildSqlStringFromClientCriteria(String schemaSql, final SearchParameters searchParameters, List<Object> paramList) {
@@ -275,8 +280,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
         }
 
         if (displayName != null) {
-            // extraCriteria += " and concat(ifnull(c.firstname, ''),
-            // if(c.firstname > '',' ', '') , ifnull(c.lastname, '')) like "
+            // extraCriteria += " and concatcoalesce(c.firstname, ''),
+            // if(c.firstname > '',' ', '') , coalesce(c.lastname, '')) like "
             paramList.add("%" + displayName + "%");
             extraCriteria += " and c.display_name like ? ";
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
index 658d693..0cdeb6f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientTransactionReadPlatformServiceImpl.java
@@ -29,6 +29,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.client.data.ClientTransactionData;
 import org.apache.fineract.portfolio.client.domain.ClientEnumerations;
@@ -46,14 +47,17 @@ import org.springframework.stereotype.Service;
 public class ClientTransactionReadPlatformServiceImpl implements ClientTransactionReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final ClientTransactionMapper clientTransactionMapper;
-    private final PaginationHelper<ClientTransactionData> paginationHelper;
+    private final PaginationHelper paginationHelper;
 
     @Autowired
-    public ClientTransactionReadPlatformServiceImpl(final RoutingDataSource dataSource) {
+    public ClientTransactionReadPlatformServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
         this.clientTransactionMapper = new ClientTransactionMapper();
-        this.paginationHelper = new PaginationHelper<>();
+        this.paginationHelper = paginationHelper;
     }
 
     private static final class ClientTransactionMapper implements RowMapper<ClientTransactionData> {
@@ -137,21 +141,23 @@ public class ClientTransactionReadPlatformServiceImpl implements ClientTransacti
     public Page<ClientTransactionData> retrieveAllTransactions(Long clientId, SearchParameters searchParameters) {
         Object[] parameters = new Object[1];
         final StringBuilder sqlBuilder = new StringBuilder();
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ").append(this.clientTransactionMapper.schema()).append(" where c.id = ? ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ").append(this.clientTransactionMapper.schema())
+                .append(" where c.id = ? ");
         parameters[0] = clientId;
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         sqlBuilder.append(" order by tr.transaction_date DESC, tr.created_date DESC, tr.id DESC ");
 
         // apply limit and offsets
+
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), parameters,
-                this.clientTransactionMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), parameters, this.clientTransactionMapper);
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java
index 1784822..93fed5f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java
@@ -42,6 +42,7 @@ import org.apache.fineract.infrastructure.core.api.JsonQuery;
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.calendar.domain.Calendar;
@@ -90,12 +91,13 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
     private final CollectionSheetGenerateCommandFromApiJsonDeserializer collectionSheetGenerateCommandFromApiJsonDeserializer;
     private final CalendarRepositoryWrapper calendarRepositoryWrapper;
     private final AttendanceDropdownReadPlatformService attendanceDropdownReadPlatformService;
-    private final MandatorySavingsCollectionsheetExtractor mandatorySavingsExtractor = new MandatorySavingsCollectionsheetExtractor();
+    private final MandatorySavingsCollectionsheetExtractor mandatorySavingsExtractor;
     private final CodeValueReadPlatformService codeValueReadPlatformService;
     private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
     private final CalendarReadPlatformService calendarReadPlatformService;
     private final ConfigurationDomainService configurationDomainService;
     private final CalendarInstanceRepository calendarInstanceRepository;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public CollectionSheetReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
@@ -106,7 +108,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
             final CodeValueReadPlatformService codeValueReadPlatformService,
             final PaymentTypeReadPlatformService paymentTypeReadPlatformService,
             final CalendarReadPlatformService calendarReadPlatformService, final ConfigurationDomainService configurationDomainService,
-            final CalendarInstanceRepository calendarInstanceRepository) {
+            final CalendarInstanceRepository calendarInstanceRepository, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.centerReadPlatformService = centerReadPlatformService;
         this.namedParameterjdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
@@ -119,6 +121,8 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
         this.calendarReadPlatformService = calendarReadPlatformService;
         this.configurationDomainService = configurationDomainService;
         this.calendarInstanceRepository = calendarInstanceRepository;
+        this.sqlGenerator = sqlGenerator;
+        mandatorySavingsExtractor = new MandatorySavingsCollectionsheetExtractor(sqlGenerator);
     }
 
     /*
@@ -215,6 +219,12 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
 
     private static final class JLGCollectionSheetFaltDataMapper implements RowMapper<JLGCollectionSheetFlatData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        JLGCollectionSheetFaltDataMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String collectionSheetSchema(final boolean isCenterCollection) {
             StringBuilder sql = new StringBuilder(400);
             sql.append("SELECT loandata.*, sum(lc.amount_outstanding_derived) as chargesDue from ")
@@ -223,7 +233,9 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
                     .append("gl.level_name As levelName, ").append("cl.id As clientId, ").append("ln.id As loanId, ")
                     .append("ln.account_no As accountId, ").append("ln.loan_status_id As accountStatusId, ")
                     .append("pl.short_name As productShortName, ").append("ln.product_id As productId, ")
-                    .append("ln.currency_code as currencyCode, ln.currency_digits as currencyDigits, ln.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, ")
+                    .append("ln.currency_code as currencyCode, ln.currency_digits as currencyDigits, ln.currency_multiplesof as inMultiplesOf, rc."
+                            + sqlGenerator.escape("name")
+                            + " as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, ")
                     .append("(CASE WHEN ln.loan_status_id = 200  THEN  ln.principal_amount  ELSE  null END) As disbursementAmount, ")
                     .append("sum(COALESCE((CASE WHEN ln.loan_status_id = 300 THEN ls.principal_amount ELSE  0.0 END), 0.0) - COALESCE((CASE WHEN ln.loan_status_id = 300 THEN  ls.principal_completed_derived ELSE  0.0 END), 0.0)) As principalDue, ")
                     .append("ln.principal_repaid_derived As principalPaid, ")
@@ -237,7 +249,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
                     .append("JOIN m_group_client gc ON gc.group_id = gp.id ").append("JOIN m_client cl ON cl.id = gc.client_id ")
                     .append("LEFT JOIN m_loan ln ON cl.id = ln.client_id  and ln.group_id=gp.id AND ln.group_id is not null AND ( ln.loan_status_id = 300 ) ")
                     .append("LEFT JOIN m_product_loan pl ON pl.id = ln.product_id ")
-                    .append("LEFT JOIN m_currency rc on rc.`code` = ln.currency_code ")
+                    .append("LEFT JOIN m_currency rc on rc." + sqlGenerator.escape("code") + " = ln.currency_code ")
                     .append("LEFT JOIN m_loan_repayment_schedule ls ON ls.loan_id = ln.id AND ls.completed_derived = 0 AND ls.duedate <= :dueDate ")
                     .append("left join m_calendar_instance ci on gp.parent_id = ci.entity_id and ci.entity_type_enum =:entityTypeId ")
                     .append("left join m_meeting mt on ci.id = mt.calendar_instance_id and mt.meeting_date =:dueDate ")
@@ -354,7 +366,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
         final String hierarchy = currentUser.getOffice().getHierarchy();
         final String officeHierarchy = hierarchy + "%";
 
-        final JLGCollectionSheetFaltDataMapper mapper = new JLGCollectionSheetFaltDataMapper();
+        final JLGCollectionSheetFaltDataMapper mapper = new JLGCollectionSheetFaltDataMapper(sqlGenerator);
 
         final SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("dueDate", transactionDateStr)
                 .addValue("groupId", group.getId()).addValue("officeHierarchy", officeHierarchy)
@@ -457,7 +469,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
         final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
         final String dueDateStr = df.format(Date.from(transactionDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
 
-        final JLGCollectionSheetFaltDataMapper mapper = new JLGCollectionSheetFaltDataMapper();
+        final JLGCollectionSheetFaltDataMapper mapper = new JLGCollectionSheetFaltDataMapper(sqlGenerator);
 
         StringBuilder sql = new StringBuilder(mapper.collectionSheetSchema(true));
 
@@ -487,6 +499,11 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
     private static final class MandatorySavingsCollectionsheetExtractor implements ResultSetExtractor<Collection<JLGGroupData>> {
 
         private final GroupSavingsDataMapper groupSavingsDataMapper = new GroupSavingsDataMapper();
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        MandatorySavingsCollectionsheetExtractor(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
 
         public String collectionSheetSchema(final boolean isCenterCollection) {
 
@@ -497,7 +514,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
                     .append("sa.account_no As accountId, ").append("sa.status_enum As accountStatusId, ")
                     .append("sp.short_name As productShortName, ").append("sp.id As productId, ")
                     .append("sa.currency_code as currencyCode, ").append("sa.currency_digits as currencyDigits, ")
-                    .append("sa.currency_multiplesof as inMultiplesOf, ").append("rc.`name` as currencyName, ")
+                    .append("sa.currency_multiplesof as inMultiplesOf, ").append("rc." + sqlGenerator.escape("name") + " as currencyName, ")
                     .append("rc.display_symbol as currencyDisplaySymbol, ")
                     .append("(CASE WHEN sa.deposit_type_enum=100 THEN 'Saving Deposit' ELSE (CASE WHEN sa.deposit_type_enum=300 THEN 'Recurring Deposit' ELSE 'Current Deposit' END) END) as depositAccountType, ")
                     .append("rc.internationalized_name_code as currencyNameCode, ")
@@ -511,7 +528,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
                     .append("JOIN m_savings_product sp ON sa.product_id=sp.id ")
                     .append("LEFT JOIN m_deposit_account_recurring_detail dard ON sa.id = dard.savings_account_id AND dard.is_mandatory = true AND dard.is_calendar_inherited = true ")
                     .append("LEFT JOIN m_mandatory_savings_schedule mss ON mss.savings_account_id=sa.id AND mss.duedate <= :dueDate ")
-                    .append("LEFT JOIN m_currency rc on rc.`code` = sa.currency_code ");
+                    .append("LEFT JOIN m_currency rc on rc." + sqlGenerator.escape("code") + " = sa.currency_code ");
 
             if (isCenterCollection) {
                 sql.append("WHERE gp.parent_id = :centerId ");
@@ -680,7 +697,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
         final boolean checkForStaffId = staffId != null;
 
         final IndividualCollectionSheetFaltDataMapper mapper = new IndividualCollectionSheetFaltDataMapper(checkForOfficeId,
-                checkForStaffId);
+                checkForStaffId, sqlGenerator);
 
         final SqlParameterSource namedParameters = new MapSqlParameterSource().addValue("dueDate", transactionDateStr)
                 .addValue("officeHierarchy", officeHierarchy);
@@ -696,7 +713,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
                 .query(mapper.sqlSchema(), namedParameters, mapper);
 
         IndividualMandatorySavingsCollectionsheetExtractor mandatorySavingsExtractor = new IndividualMandatorySavingsCollectionsheetExtractor(
-                checkForOfficeId, checkForStaffId);
+                checkForOfficeId, checkForStaffId, sqlGenerator);
         // mandatory savings data for collection sheet
         Collection<IndividualClientData> clientData = this.namedParameterjdbcTemplate
                 .query(mandatorySavingsExtractor.collectionSheetSchema(), namedParameters, mandatorySavingsExtractor);
@@ -714,15 +731,16 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
 
         private final String sql;
 
-        IndividualCollectionSheetFaltDataMapper(final boolean checkForOfficeId, final boolean checkforStaffId) {
+        IndividualCollectionSheetFaltDataMapper(final boolean checkForOfficeId, final boolean checkforStaffId,
+                DatabaseSpecificSQLGenerator sqlGenerator) {
             StringBuilder sb = new StringBuilder();
             sb.append("SELECT loandata.*, sum(lc.amount_outstanding_derived) as chargesDue ");
             sb.append("from (SELECT cl.display_name As clientName, ");
             sb.append("cl.id As clientId, ln.id As loanId, ln.account_no As accountId, ln.loan_status_id As accountStatusId,");
             sb.append(" pl.short_name As productShortName, ln.product_id As productId, ");
             sb.append("ln.currency_code as currencyCode, ln.currency_digits as currencyDigits, ln.currency_multiplesof as inMultiplesOf, ");
-            sb.append(
-                    "rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, ");
+            sb.append("rc." + sqlGenerator.escape("name")
+                    + " as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, ");
             sb.append("(CASE WHEN ln.loan_status_id = 200 THEN ln.principal_amount ELSE null END) As disbursementAmount, ");
             sb.append(
                     "sum(COALESCE((CASE WHEN ln.loan_status_id = 300 THEN ls.principal_amount ELSE 0.0 END), 0.0) - COALESCE((CASE WHEN ln.loan_status_id = 300 THEN ls.principal_completed_derived ELSE 0.0 END), 0.0)) As principalDue, ");
@@ -737,7 +755,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
             sb.append("JOIN m_client cl ON cl.id = ln.client_id  ");
             sb.append("LEFT JOIN m_office of ON of.id = cl.office_id  AND of.hierarchy like :officeHierarchy ");
             sb.append("LEFT JOIN m_product_loan pl ON pl.id = ln.product_id ");
-            sb.append("LEFT JOIN m_currency rc on rc.`code` = ln.currency_code ");
+            sb.append("LEFT JOIN m_currency rc on rc." + sqlGenerator.escape("code") + " = ln.currency_code ");
             sb.append("JOIN m_loan_repayment_schedule ls ON ls.loan_id = ln.id AND ls.completed_derived = 0 AND ls.duedate <= :dueDate ");
             sb.append("where ");
             if (checkForOfficeId) {
@@ -804,7 +822,8 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
 
         private final String sql;
 
-        IndividualMandatorySavingsCollectionsheetExtractor(final boolean checkForOfficeId, final boolean checkforStaffId) {
+        IndividualMandatorySavingsCollectionsheetExtractor(final boolean checkForOfficeId, final boolean checkforStaffId,
+                DatabaseSpecificSQLGenerator sqlGenerator) {
 
             final StringBuilder sb = new StringBuilder(400);
             sb.append(
@@ -812,8 +831,8 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
             sb.append("sa.id As savingsId, sa.account_no As accountId, sa.status_enum As accountStatusId, ");
             sb.append("sp.short_name As productShortName, sp.id As productId, ");
             sb.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, sa.currency_multiplesof as inMultiplesOf, ");
-            sb.append(
-                    "rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, ");
+            sb.append("rc." + sqlGenerator.escape("name")
+                    + " as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, ");
             sb.append("SUM(COALESCE(mss.deposit_amount,0) - coalesce(mss.deposit_amount_completed_derived,0)) as dueAmount ");
             sb.append("FROM m_savings_account sa ");
             sb.append("JOIN m_client cl ON cl.id = sa.client_id ");
@@ -823,7 +842,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe
             sb.append(
                     "LEFT JOIN m_mandatory_savings_schedule mss ON mss.savings_account_id=sa.id AND mss.completed_derived = 0 AND mss.duedate <= :dueDate ");
             sb.append("LEFT JOIN m_office of ON of.id = cl.office_id AND of.hierarchy like :officeHierarchy ");
-            sb.append("LEFT JOIN m_currency rc on rc.`code` = sa.currency_code ");
+            sb.append("LEFT JOIN m_currency rc on rc." + sqlGenerator.escape("code") + " = sa.currency_code ");
             sb.append("WHERE sa.status_enum=300 and sa.group_id is null and sa.deposit_type_enum in (100,300,400) ");
             sb.append("and (cl.status_enum = 300 or (cl.status_enum = 600 and cl.closedon_date >= :dueDate)) ");
             if (checkForOfficeId) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java
index 3d952bc..86448f7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/CenterReadPlatformServiceImpl.java
@@ -46,6 +46,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.infrastructure.security.utils.SQLBuilder;
@@ -94,7 +95,8 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
     private final CenterDataMapper centerMapper = new CenterDataMapper();
     private final GroupDataMapper groupDataMapper = new GroupDataMapper();
 
-    private final PaginationHelper<CenterData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PaginationParametersDataValidator paginationParametersDataValidator;
     private static final Set<String> SUPPORTED_ORDER_BY_VALUES = new HashSet<>(Arrays.asList("id", "name", "officeId", "officeName"));
 
@@ -104,7 +106,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
             final StaffReadPlatformService staffReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService,
             final PaginationParametersDataValidator paginationParametersDataValidator,
             final ConfigurationDomainService configurationDomainService, final CalendarReadPlatformService calendarReadPlatformService,
-            final ColumnValidator columnValidator) {
+            final ColumnValidator columnValidator, DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.clientReadPlatformService = clientReadPlatformService;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
@@ -115,6 +117,8 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
         this.configurationDomainService = configurationDomainService;
         this.calendarReadPlatformService = calendarReadPlatformService;
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     // 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where
@@ -336,7 +340,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
         final String hierarchySearchString = hierarchy + "%";
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.centerMapper.schema());
         final SQLBuilder extraCriteria = getCenterExtraCriteria(this.centerMapper.schema(), searchParameters);
         extraCriteria.addNonNullCriteria("o.hierarchy like ", hierarchySearchString);
@@ -349,15 +353,15 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), extraCriteria.getArguments(),
-                this.centerMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), extraCriteria.getArguments(), this.centerMapper);
     }
 
     @Override
@@ -383,9 +387,11 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
             }
 
             if (searchParameters.isLimited()) {
-                sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+                sqlBuilder.append(" ");
                 if (searchParameters.isOffset()) {
-                    sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+                } else {
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
                 }
             }
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupReadPlatformServiceImpl.java
index c048ec3..b991fb0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupReadPlatformServiceImpl.java
@@ -35,6 +35,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.infrastructure.security.utils.SQLBuilder;
@@ -67,7 +68,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
     private final CodeValueReadPlatformService codeValueReadPlatformService;
 
     private final AllGroupTypesDataMapper allGroupTypesDataMapper = new AllGroupTypesDataMapper();
-    private final PaginationHelper<GroupGeneralData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PaginationParametersDataValidator paginationParametersDataValidator;
     private final ColumnValidator columnValidator;
 
@@ -77,7 +79,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
     public GroupReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
             final CenterReadPlatformService centerReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
             final StaffReadPlatformService staffReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService,
-            final PaginationParametersDataValidator paginationParametersDataValidator, final ColumnValidator columnValidator) {
+            final PaginationParametersDataValidator paginationParametersDataValidator, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.centerReadPlatformService = centerReadPlatformService;
@@ -86,6 +89,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
         this.codeValueReadPlatformService = codeValueReadPlatformService;
         this.paginationParametersDataValidator = paginationParametersDataValidator;
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -144,7 +149,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
         final String hierarchySearchString = hierarchy + "%";
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.allGroupTypesDataMapper.schema());
 
         final SQLBuilder extraCriteria = getGroupExtraCriteria(this.allGroupTypesDataMapper.schema(), searchParameters);
@@ -163,8 +168,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), extraCriteria.getArguments(),
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), extraCriteria.getArguments(),
                 this.allGroupTypesDataMapper);
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java
index 84877b2..e2479f4 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartReadPlatformServiceImpl.java
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformSer
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.client.api.ClientApiConstants;
@@ -54,21 +55,24 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
     private final PlatformSecurityContext context;
     private final JdbcTemplate jdbcTemplate;
     private final InterestRateChartMapper chartRowMapper = new InterestRateChartMapper();
-    private final InterestRateChartExtractor chartExtractor = new InterestRateChartExtractor();
+    private final InterestRateChartExtractor chartExtractor;
     private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService;
     private final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService;
     private final CodeValueReadPlatformService codeValueReadPlatformService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public InterestRateChartReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource,
             InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService,
             final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService,
-            final CodeValueReadPlatformService codeValueReadPlatformService) {
+            final CodeValueReadPlatformService codeValueReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.chartDropdownReadPlatformService = chartDropdownReadPlatformService;
         this.interestIncentiveDropdownReadPlatformService = interestIncentiveDropdownReadPlatformService;
         this.codeValueReadPlatformService = codeValueReadPlatformService;
+        this.sqlGenerator = sqlGenerator;
+        chartExtractor = new InterestRateChartExtractor(this.sqlGenerator);
     }
 
     @Override
@@ -180,7 +184,7 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
     private static final class InterestRateChartExtractor implements ResultSetExtractor<Collection<InterestRateChartData>> {
 
         InterestRateChartMapper chartMapper = new InterestRateChartMapper();
-        InterestRateChartSlabExtractor chartSlabsMapper = new InterestRateChartSlabExtractor();
+        InterestRateChartSlabExtractor chartSlabsMapper;
 
         private final String schemaSql;
 
@@ -188,7 +192,8 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
             return this.schemaSql;
         }
 
-        private InterestRateChartExtractor() {
+        private InterestRateChartExtractor(DatabaseSpecificSQLGenerator sqlGenerator) {
+            chartSlabsMapper = new InterestRateChartSlabExtractor(sqlGenerator);
             final StringBuilder sqlBuilder = new StringBuilder(400);
 
             sqlBuilder.append("irc.id as ircId, irc.name as ircName, irc.description as ircDescription,")
@@ -206,7 +211,7 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
                     .append("from ")
                     .append("m_interest_rate_chart irc left join m_interest_rate_slab ircd on irc.id=ircd.interest_rate_chart_id ")
                     .append(" left join m_interest_incentives iri on iri.interest_rate_slab_id = ircd.id ")
-                    .append(" left join m_code_value code on code.id = iri.attribute_value ")
+                    .append(" left join m_code_value code on " + sqlGenerator.castChar("code.id") + " = iri.attribute_value ")
                     .append("left join m_currency curr on ircd.currency_code= curr.code ")
                     .append("left join m_deposit_product_interest_rate_chart dpirc on irc.id=dpirc.interest_rate_chart_id ")
                     .append("left join m_savings_product sp on sp.id=dpirc.deposit_product_id ");
@@ -289,7 +294,7 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
             return this.schemaSql;
         }
 
-        private InterestRateChartSlabsMapper() {
+        private InterestRateChartSlabsMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
             final StringBuilder sqlBuilder = new StringBuilder(400);
 
             sqlBuilder.append("ircd.id as ircdId, ircd.description as ircdDescription, ircd.period_type_enum ircdPeriodTypeId, ").append(
@@ -302,7 +307,7 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
                     .append(" iri.incentive_type as incentiveType, iri.amount as amount, ").append("code.code_value as attributeValueDesc ")
                     .append("from ").append("m_interest_rate_slab ircd ")
                     .append(" left join m_interest_incentives iri on iri.interest_rate_slab_id = ircd.id ")
-                    .append(" left join m_code_value code on code.id = iri.attribute_value ")
+                    .append(" left join m_code_value code on " + sqlGenerator.castChar("code.id") + " = iri.attribute_value ")
                     .append("left join m_currency curr on ircd.currency_code= curr.code ");
             this.schemaSql = sqlBuilder.toString();
         }
@@ -347,7 +352,7 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
 
     private static final class InterestRateChartSlabExtractor implements ResultSetExtractor<InterestRateChartSlabData> {
 
-        InterestRateChartSlabsMapper chartSlabsMapper = new InterestRateChartSlabsMapper();
+        InterestRateChartSlabsMapper chartSlabsMapper;
         InterestIncentiveMapper incentiveMapper = new InterestIncentiveMapper();
 
         private final String schemaSql;
@@ -357,7 +362,8 @@ public class InterestRateChartReadPlatformServiceImpl implements InterestRateCha
             return this.schemaSql;
         }
 
-        private InterestRateChartSlabExtractor() {
+        private InterestRateChartSlabExtractor(DatabaseSpecificSQLGenerator sqlGenerator) {
+            chartSlabsMapper = new InterestRateChartSlabsMapper(sqlGenerator);
             this.schemaSql = chartSlabsMapper.schema();
         }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java
index aecc679..f1cfbab 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/service/InterestRateChartSlabReadPlatformServiceImpl.java
@@ -29,6 +29,7 @@ import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformSer
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.client.api.ClientApiConstants;
@@ -49,21 +50,24 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat
 
     private final PlatformSecurityContext context;
     private final JdbcTemplate jdbcTemplate;
-    private final InterestRateChartSlabExtractor chartSlabExtractor = new InterestRateChartSlabExtractor();
+    private final InterestRateChartSlabExtractor chartSlabExtractor;
     private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService;
     private final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService;
     private final CodeValueReadPlatformService codeValueReadPlatformService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public InterestRateChartSlabReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource,
             InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService,
             final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService,
-            final CodeValueReadPlatformService codeValueReadPlatformService) {
+            final CodeValueReadPlatformService codeValueReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.chartDropdownReadPlatformService = chartDropdownReadPlatformService;
         this.interestIncentiveDropdownReadPlatformService = interestIncentiveDropdownReadPlatformService;
         this.codeValueReadPlatformService = codeValueReadPlatformService;
+        this.sqlGenerator = sqlGenerator;
+        chartSlabExtractor = new InterestRateChartSlabExtractor(sqlGenerator);
     }
 
     @Override
@@ -131,7 +135,7 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat
             return this.schemaSql;
         }
 
-        private InterestRateChartSlabsMapper() {
+        private InterestRateChartSlabsMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
             final StringBuilder sqlBuilder = new StringBuilder(400);
 
             sqlBuilder.append("ircd.id as ircdId, ircd.description as ircdDescription, ircd.period_type_enum ircdPeriodTypeId, ").append(
@@ -144,7 +148,7 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat
                     .append(" iri.incentive_type as incentiveType, iri.amount as amount, ").append("code.code_value as attributeValueDesc ")
                     .append("from ").append("m_interest_rate_slab ircd ")
                     .append(" left join m_interest_incentives iri on iri.interest_rate_slab_id = ircd.id ")
-                    .append(" left join m_code_value code on code.id = iri.attribute_value ")
+                    .append(" left join m_code_value code on " + sqlGenerator.castChar("code.id") + " = iri.attribute_value ")
                     .append("left join m_currency curr on ircd.currency_code= curr.code ");
             this.schemaSql = sqlBuilder.toString();
         }
@@ -186,7 +190,7 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat
 
     private static final class InterestRateChartSlabExtractor implements ResultSetExtractor<Collection<InterestRateChartSlabData>> {
 
-        InterestRateChartSlabsMapper chartSlabsMapper = new InterestRateChartSlabsMapper();
+        InterestRateChartSlabsMapper chartSlabsMapper;
         InterestIncentiveMapper incentiveMapper = new InterestIncentiveMapper();
 
         private final String schemaSql;
@@ -195,7 +199,8 @@ public class InterestRateChartSlabReadPlatformServiceImpl implements InterestRat
             return this.schemaSql;
         }
 
-        private InterestRateChartSlabExtractor() {
+        private InterestRateChartSlabExtractor(DatabaseSpecificSQLGenerator sqlGenerator) {
+            chartSlabsMapper = new InterestRateChartSlabsMapper(sqlGenerator);
             this.schemaSql = chartSlabsMapper.schema();
         }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 0cfe9b5..864536a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -182,7 +182,7 @@ public class Loan extends AbstractPersistableCustom {
     @Column(name = "loan_type_enum", nullable = false)
     private Integer loanType;
 
-    @ManyToOne(fetch = FetchType.EAGER)
+    @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "product_id", nullable = false)
     private LoanProduct loanProduct;
 
@@ -323,7 +323,7 @@ public class Loan extends AbstractPersistableCustom {
     private Set<LoanOfficerAssignmentHistory> loanOfficerHistory;
 
     @OrderBy(value = "installmentNumber")
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.EAGER)
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.LAZY)
     private List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = new ArrayList<>();
 
     @OrderBy(value = "dateOf, id")
@@ -362,7 +362,7 @@ public class Loan extends AbstractPersistableCustom {
     @OrderBy(value = "expectedDisbursementDate, id")
     private List<LoanDisbursementDetails> disbursementDetails = new ArrayList<>();
 
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.EAGER)
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch = FetchType.LAZY)
     private List<PostDatedChecks> postDatedChecks = new ArrayList<>();
 
     @OrderBy(value = "termApplicableFrom, id")
@@ -372,7 +372,7 @@ public class Loan extends AbstractPersistableCustom {
     @Column(name = "total_recovered_derived", scale = 6, precision = 19)
     private BigDecimal totalRecovered;
 
-    @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch = FetchType.EAGER)
+    @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch = FetchType.LAZY)
     private LoanInterestRecalculationDetails loanInterestRecalculationDetails;
 
     @Column(name = "is_npa", nullable = false)
@@ -408,7 +408,7 @@ public class Loan extends AbstractPersistableCustom {
     @Column(name = "is_topup", nullable = false)
     private boolean isTopup = false;
 
-    @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch = FetchType.EAGER)
+    @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch = FetchType.LAZY)
     private LoanTopupDetails loanTopupDetails;
 
     @OneToMany(fetch = FetchType.LAZY)
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
index 85ade28..fa2e851 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
@@ -57,8 +57,10 @@ import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundEx
 import org.apache.fineract.portfolio.loanproduct.serialization.LoanProductDataValidator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
+@Transactional
 public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleCalculationPlatformService {
 
     private final CalculateLoanScheduleQueryFromApiJsonHelper fromApiJsonDeserializer;
@@ -205,6 +207,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
     }
 
     @Override
+    @Transactional(readOnly = true)
     public LoanScheduleData generateLoanScheduleForVariableInstallmentRequest(Long loanId, final String json) {
         final Loan loan = this.loanAssembler.assembleFrom(loanId);
         this.loanScheduleAssembler.assempleVariableScheduleFrom(loan, json);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
index 3aaa9a6..b613eff 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryReadPlatformServiceImpl.java
@@ -43,8 +43,10 @@ import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.ResultSetExtractor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
+@Transactional(readOnly = true)
 public class LoanScheduleHistoryReadPlatformServiceImpl implements LoanScheduleHistoryReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryWritePlatformServiceImpl.java
index e36cddd..1ad3031 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleHistoryWritePlatformServiceImpl.java
@@ -32,8 +32,10 @@ import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanResch
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
+@Transactional
 public class LoanScheduleHistoryWritePlatformServiceImpl implements LoanScheduleHistoryWritePlatformService {
 
     private final LoanScheduleHistoryReadPlatformService loanScheduleHistoryReadPlatformService;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
index 2ce48db..21a67de 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
@@ -37,8 +37,10 @@ import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
+@Transactional
 public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePlatformService {
 
     private final LoanAccountDomainService loanAccountDomainService;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
index dd3140a..8a5bc44 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualWritePlatformServiceImpl.java
@@ -34,6 +34,7 @@ import javax.sql.DataSource;
 import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
 import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
 import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
@@ -63,6 +64,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
     private final LoanChargeReadPlatformService loanChargeReadPlatformService;
     private final JdbcTemplate jdbcTemplate;
     private final DataSource dataSource;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final JournalEntryWritePlatformService journalEntryWritePlatformService;
     private final AppUserRepositoryWrapper userRepository;
     private final LoanRepositoryWrapper loanRepositoryWrapper;
@@ -72,9 +74,11 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
     public LoanAccrualWritePlatformServiceImpl(final RoutingDataSource dataSource, final LoanReadPlatformService loanReadPlatformService,
             final JournalEntryWritePlatformService journalEntryWritePlatformService,
             final LoanChargeReadPlatformService loanChargeReadPlatformService, final AppUserRepositoryWrapper userRepository,
-            final LoanRepositoryWrapper loanRepositoryWrapper, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository) {
+            final LoanRepositoryWrapper loanRepositoryWrapper, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
+            DatabaseSpecificSQLGenerator sqlGenerator) {
         this.loanReadPlatformService = loanReadPlatformService;
         this.dataSource = dataSource;
+        this.sqlGenerator = sqlGenerator;
         this.jdbcTemplate = new JdbcTemplate(this.dataSource);
         this.journalEntryWritePlatformService = journalEntryWritePlatformService;
         this.loanChargeReadPlatformService = loanChargeReadPlatformService;
@@ -274,7 +278,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
                 LoanTransactionType.ACCRUAL.getValue(), Date.from(accruedTill.atStartOfDay(ZoneId.systemDefault()).toInstant()), amount,
                 interestportion, feeportion, penaltyportion, DateUtils.getDateOfTenant());
         @SuppressWarnings("deprecation")
-        final Long transactonId = this.jdbcTemplate.queryForObject("SELECT LAST_INSERT_ID()", Long.class);
+        final Long transactonId = this.jdbcTemplate.queryForObject("SELECT " + sqlGenerator.lastInsertId(), Long.class);
 
         Map<LoanChargeData, BigDecimal> applicableCharges = scheduleAccrualData.getApplicableCharges();
         String chargespaidSql = "INSERT INTO m_loan_charge_paid_by (loan_transaction_id, loan_charge_id, amount,installment_number) VALUES (?,?,?,?)";
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java
index 5c25c21..189b069 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java
@@ -32,6 +32,7 @@ import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
 import org.apache.fineract.infrastructure.jobs.service.JobName;
 import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BusinessEntity;
@@ -58,14 +59,16 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService, Bus
 
     private static final Logger LOG = LoggerFactory.getLogger(LoanArrearsAgingServiceImpl.class);
     private final BusinessEventNotifierService businessEventNotifierService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
     private final JdbcTemplate jdbcTemplate;
 
     @Autowired
-    public LoanArrearsAgingServiceImpl(final RoutingDataSource dataSource,
-            final BusinessEventNotifierService businessEventNotifierService) {
+    public LoanArrearsAgingServiceImpl(final RoutingDataSource dataSource, final BusinessEventNotifierService businessEventNotifierService,
+            DatabaseSpecificSQLGenerator sqlGenerator) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.businessEventNotifierService = businessEventNotifierService;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @PostConstruct
@@ -114,7 +117,8 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService, Bus
         updateSqlBuilder.append(" left join m_product_loan_recalculation_details prd on prd.product_id = ml.product_id ");
         updateSqlBuilder.append(" WHERE ml.loan_status_id = 300 "); // active
         updateSqlBuilder.append(" and mr.completed_derived is false ");
-        updateSqlBuilder.append(" and mr.duedate < SUBDATE(CURDATE(),INTERVAL  COALESCE(ml.grace_on_arrears_ageing, 0) day) ");
+        updateSqlBuilder.append(" and mr.duedate < ")
+                .append(sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day")).append(" ");
         updateSqlBuilder.append(" and (prd.arrears_based_on_original_schedule = false or prd.arrears_based_on_original_schedule is null) ");
         updateSqlBuilder.append(" GROUP BY ml.id");
 
@@ -134,7 +138,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService, Bus
         int count = this.jdbcTemplate.queryForObject("select count(mla.loan_id) from m_loan_arrears_aging mla where mla.loan_id =?",
                 Integer.class, loan.getId());
         List<String> updateStatement = new ArrayList<>();
-        OriginalScheduleExtractor originalScheduleExtractor = new OriginalScheduleExtractor(loan.getId().toString());
+        OriginalScheduleExtractor originalScheduleExtractor = new OriginalScheduleExtractor(loan.getId().toString(), sqlGenerator);
         Map<Long, List<LoanSchedulePeriodData>> scheduleDate = this.jdbcTemplate.query(originalScheduleExtractor.schema,
                 originalScheduleExtractor);
         if (scheduleDate.size() > 0) {
@@ -204,13 +208,14 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService, Bus
         loanIdentifier.append("INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id ");
         loanIdentifier.append(
                 "inner join m_product_loan_recalculation_details prd on prd.product_id = ml.product_id and prd.arrears_based_on_original_schedule = true  ");
-        loanIdentifier.append(
-                "WHERE ml.loan_status_id = 300  and mr.completed_derived is false  and mr.duedate < SUBDATE(CURDATE(),INTERVAL  COALESCE(ml.grace_on_arrears_ageing, 0) day) group by ml.id");
+        loanIdentifier.append("WHERE ml.loan_status_id = 300  and mr.completed_derived is false  and mr.duedate < ")
+                .append(sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day"))
+                .append(" group by ml.id");
         List<Long> loanIds = this.jdbcTemplate.queryForList(loanIdentifier.toString(), Long.class);
         if (!loanIds.isEmpty()) {
             String loanIdsAsString = loanIds.toString();
             loanIdsAsString = loanIdsAsString.substring(1, loanIdsAsString.length() - 1);
-            OriginalScheduleExtractor originalScheduleExtractor = new OriginalScheduleExtractor(loanIdsAsString);
+            OriginalScheduleExtractor originalScheduleExtractor = new OriginalScheduleExtractor(loanIdsAsString, sqlGenerator);
             Map<Long, List<LoanSchedulePeriodData>> scheduleDate = this.jdbcTemplate.query(originalScheduleExtractor.schema,
                     originalScheduleExtractor);
 
@@ -419,13 +424,14 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService, Bus
 
         private final String schema;
 
-        OriginalScheduleExtractor(final String loanIdsAsString) {
+        OriginalScheduleExtractor(final String loanIdsAsString, DatabaseSpecificSQLGenerator sqlGenerator) {
             final StringBuilder scheduleDetail = new StringBuilder();
             scheduleDetail.append("select ml.id as loanId, mr.duedate as dueDate, mr.principal_amount as principalAmount, ");
             scheduleDetail.append(
                     "mr.interest_amount as interestAmount, mr.fee_charges_amount as feeAmount, mr.penalty_charges_amount as penaltyAmount  ");
             scheduleDetail.append("from m_loan ml  INNER JOIN m_loan_repayment_schedule_history mr on mr.loan_id = ml.id ");
-            scheduleDetail.append("where mr.duedate  < SUBDATE(CURDATE(),INTERVAL  COALESCE(ml.grace_on_arrears_ageing, 0) day) and ");
+            scheduleDetail.append("where mr.duedate  < "
+                    + sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(ml.grace_on_arrears_ageing, 0)", "day") + " and ");
             scheduleDetail.append("ml.id IN(").append(loanIdsAsString).append(") and  mr.version = (");
             scheduleDetail.append("select max(lrs.version) from m_loan_repayment_schedule_history lrs where mr.loan_id = lrs.loan_id");
             scheduleDetail.append(") order by ml.id,mr.duedate");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
index 5872fb2..029effa 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java
@@ -47,6 +47,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
@@ -129,9 +130,11 @@ import org.springframework.jdbc.core.ResultSetExtractor;
 import org.springframework.jdbc.core.RowMapper;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 @Service
+@Transactional(readOnly = true)
 public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
@@ -147,8 +150,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
     private final CodeValueReadPlatformService codeValueReadPlatformService;
     private final CalendarReadPlatformService calendarReadPlatformService;
     private final StaffReadPlatformService staffReadPlatformService;
-    private final PaginationHelper<LoanAccountData> paginationHelper = new PaginationHelper<>();
-    private final LoanMapper loaanLoanMapper = new LoanMapper();
+    private final PaginationHelper paginationHelper;
+    private final LoanMapper loaanLoanMapper;
     private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
     private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
     private final PaymentTypeReadPlatformService paymentTypeReadPlatformService;
@@ -158,6 +161,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
     private final ConfigurationDomainService configurationDomainService;
     private final AccountDetailsReadPlatformService accountDetailsReadPlatformService;
     private final ColumnValidator columnValidator;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public LoanReadPlatformServiceImpl(final PlatformSecurityContext context,
@@ -172,7 +176,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
             final FloatingRatesReadPlatformService floatingRatesReadPlatformService, final LoanUtilService loanUtilService,
             final ConfigurationDomainService configurationDomainService,
             final AccountDetailsReadPlatformService accountDetailsReadPlatformService, final LoanRepositoryWrapper loanRepositoryWrapper,
-            final ColumnValidator columnValidator) {
+            final ColumnValidator columnValidator, DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.context = context;
         this.loanRepositoryWrapper = loanRepositoryWrapper;
         this.applicationCurrencyRepository = applicationCurrencyRepository;
@@ -194,6 +198,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         this.configurationDomainService = configurationDomainService;
         this.accountDetailsReadPlatformService = accountDetailsReadPlatformService;
         this.columnValidator = columnValidator;
+        this.loaanLoanMapper = new LoanMapper(sqlGenerator);
+        this.sqlGenerator = sqlGenerator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -204,7 +211,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
             final String hierarchy = currentUser.getOffice().getHierarchy();
             final String hierarchySearchString = hierarchy + "%";
 
-            final LoanMapper rm = new LoanMapper();
+            final LoanMapper rm = new LoanMapper(sqlGenerator);
 
             final StringBuilder sqlBuilder = new StringBuilder();
             sqlBuilder.append("select ");
@@ -225,7 +232,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
         // final AppUser currentUser = this.context.authenticatedUser();
         this.context.authenticatedUser();
-        final LoanMapper rm = new LoanMapper();
+        final LoanMapper rm = new LoanMapper(sqlGenerator);
 
         String sql = "select " + rm.loanSchema() + " where l.account_no=?";
 
@@ -238,7 +245,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
         // final AppUser currentUser = this.context.authenticatedUser();
         this.context.authenticatedUser();
-        final LoanMapper rm = new LoanMapper();
+        final LoanMapper rm = new LoanMapper(sqlGenerator);
 
         String sql = "select " + rm.loanSchema()
                 + " left join glim_parent_child_mapping as glim on glim.glim_child_account_id=l.account_no "
@@ -271,7 +278,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         try {
             this.context.authenticatedUser();
 
-            final LoanTransactionsMapper rm = new LoanTransactionsMapper();
+            final LoanTransactionsMapper rm = new LoanTransactionsMapper(sqlGenerator);
 
             // retrieve all loan transactions that are not invalid and have not
             // been 'contra'ed by another transaction
@@ -296,7 +303,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         final String hierarchySearchString = hierarchy + "%";
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.loaanLoanMapper.loanSchema());
 
         // TODO - for time being this will data scope list of loans returned to
@@ -351,17 +358,17 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
             }
 
             if (searchParameters.isLimited()) {
-                sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+                sqlBuilder.append(" ");
                 if (searchParameters.isOffset()) {
-                    sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+                } else {
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
                 }
             }
         }
         final Object[] objectArray = extraCriterias.toArray();
         final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
-                this.loaanLoanMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.loaanLoanMapper);
     }
 
     @Override
@@ -432,7 +439,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
         this.context.authenticatedUser();
 
-        RepaymentTransactionTemplateMapper mapper = new RepaymentTransactionTemplateMapper();
+        RepaymentTransactionTemplateMapper mapper = new RepaymentTransactionTemplateMapper(sqlGenerator);
         String sql = "select " + mapper.schema();
         LoanTransactionData loanTransactionData = this.jdbcTemplate.queryForObject(sql, mapper,
                 new Object[] { LoanTransactionType.REPAYMENT.getValue(), loanId, loanId });
@@ -574,7 +581,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
     public LoanTransactionData retrieveLoanTransaction(final Long loanId, final Long transactionId) {
         this.context.authenticatedUser();
         try {
-            final LoanTransactionsMapper rm = new LoanTransactionsMapper();
+            final LoanTransactionsMapper rm = new LoanTransactionsMapper(sqlGenerator);
             final String sql = "select " + rm.loanPaymentsSchema() + " where l.id = ? and tr.id = ? ";
             return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId, transactionId });
         } catch (final EmptyResultDataAccessException e) {
@@ -584,6 +591,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     private static final class LoanMapper implements RowMapper<LoanAccountData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        LoanMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String loanSchema() {
             return "l.id as id, l.account_no as accountNo, l.external_id as externalId, l.fund_id as fundId, f.name as fundName,"
                     + " l.loan_type_enum as loanType, l.loanpurpose_cv_id as loanPurposeId, cv.code_value as loanPurposeName,"
@@ -614,7 +627,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
                     + " l.allow_partial_period_interest_calcualtion as allowPartialPeriodInterestCalcualtion,"
                     + " l.loan_status_id as lifeCycleStatusId, l.loan_transaction_strategy_id as transactionStrategyId, "
                     + " lps.name as transactionStrategyName, "
-                    + " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
+                    + " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc."
+                    + sqlGenerator.escape("name")
+                    + " as currencyName, rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
                     + " l.loan_officer_id as loanOfficerId, s.display_name as loanOfficerName, "
                     + " l.principal_disbursed_derived as principalDisbursed," + " l.principal_repaid_derived as principalPaid,"
                     + " l.principal_writtenoff_derived as principalWrittenOff,"
@@ -664,8 +679,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
                     + " l.total_recovered_derived as totalRecovered" + ", topuploan.account_no as closureLoanAccountNo, "
                     + " topup.topup_amount as topupAmount " + " from m_loan l" //
                     + " join m_product_loan lp on lp.id = l.product_id" //
-                    + " left join m_loan_recalculation_details lir on lir.loan_id = l.id "
-                    + " join m_currency rc on rc.`code` = l.currency_code" //
+                    + " left join m_loan_recalculation_details lir on lir.loan_id = l.id " + " join m_currency rc on rc."
+                    + sqlGenerator.escape("code") + " = l.currency_code" //
                     + " left join m_client c on c.id = l.client_id" //
                     + " left join m_group g on g.id = l.group_id" //
                     + " left join m_loan_arrears_aging la on la.loan_id = l.id" //
@@ -1286,17 +1301,24 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     private static final class LoanTransactionsMapper implements RowMapper<LoanTransactionData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        LoanTransactionsMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String loanPaymentsSchema() {
 
-            return " tr.id as id, tr.transaction_type_enum as transactionType, tr.transaction_date as `date`, tr.amount as total, "
-                    + " tr.principal_portion_derived as principal, tr.interest_portion_derived as interest, "
+            return " tr.id as id, tr.transaction_type_enum as transactionType, tr.transaction_date as " + sqlGenerator.escape("date")
+                    + ", tr.amount as total, " + " tr.principal_portion_derived as principal, tr.interest_portion_derived as interest, "
                     + " tr.fee_charges_portion_derived as fees, tr.penalty_charges_portion_derived as penalties, "
                     + " tr.overpayment_portion_derived as overpayment, tr.outstanding_loan_balance_derived as outstandingLoanBalance, "
                     + " tr.unrecognized_income_portion as unrecognizedIncome," + " tr.submitted_on_date as submittedOnDate, "
                     + " tr.manually_adjusted_or_reversed as manuallyReversed, "
                     + " pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, "
                     + " pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, l.net_disbursal_amount as netDisbursalAmount,"
-                    + " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, "
+                    + " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc."
+                    + sqlGenerator.escape("name") + " as currencyName, "
                     + " rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
                     + " pt.value as paymentTypeName, tr.external_id as externalId, tr.office_id as officeId, office.name as officeName, "
                     + " fromtran.id as fromTransferId, fromtran.is_reversed as fromTransferReversed,"
@@ -1305,7 +1327,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
                     + " totran.id as toTransferId, totran.is_reversed as toTransferReversed,"
                     + " totran.transaction_date as toTransferDate, totran.amount as toTransferAmount,"
                     + " totran.description as toTransferDescription " + " from m_loan l join m_loan_transaction tr on tr.loan_id = l.id"
-                    + " join m_currency rc on rc.`code` = l.currency_code "
+                    + " join m_currency rc on rc." + sqlGenerator.escape("code") + " = l.currency_code "
                     + " left JOIN m_payment_detail pd ON tr.payment_detail_id = pd.id"
                     + " left join m_payment_type pt on pd.payment_type_id = pt.id" + " left join m_office office on office.id=tr.office_id"
                     + " left join m_account_transfer_transaction fromtran on fromtran.from_loan_transaction_id = tr.id "
@@ -1529,7 +1551,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         final MusoniOverdueLoanScheduleMapper rm = new MusoniOverdueLoanScheduleMapper();
 
         final StringBuilder sqlBuilder = new StringBuilder(400);
-        sqlBuilder.append("select ").append(rm.schema()).append(" where DATE_SUB(CURDATE(),INTERVAL ? DAY) > ls.duedate ")
+        sqlBuilder.append("select ").append(rm.schema())
+                .append(" where " + sqlGenerator.subDate(sqlGenerator.currentDate(), "?", "day") + " > ls.duedate ")
                 .append(" and ls.completed_derived <> true and mc.charge_applies_to_enum =1 ")
                 .append(" and ls.recalculated_interest_component <> true ")
                 .append(" and mc.charge_time_enum = 9 and ml.loan_status_id = 300 ");
@@ -1539,7 +1562,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         }
         // Only apply for duedate = yesterday (so that we don't apply
         // penalties on the duedate itself)
-        sqlBuilder.append(" and ls.duedate >= DATE_SUB(CURDATE(),INTERVAL (? + 1) DAY)");
+        sqlBuilder.append(" and ls.duedate >= " + sqlGenerator.subDate(sqlGenerator.currentDate(), "(? + 1)", "day"));
 
         return this.jdbcTemplate.query(sqlBuilder.toString(), rm, new Object[] { penaltyWaitPeriod, penaltyWaitPeriod });
     }
@@ -1560,7 +1583,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     @Override
     public Collection<DisbursementData> retrieveLoanDisbursementDetails(final Long loanId) {
-        final LoanDisbursementDetailMapper rm = new LoanDisbursementDetailMapper();
+        final LoanDisbursementDetailMapper rm = new LoanDisbursementDetailMapper(sqlGenerator);
         final String sql = "select " + rm.schema()
                 + " where dd.loan_id=? group by dd.id, lc.amount_waived_derived order by dd.expected_disburse_date";
         return this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
@@ -1568,8 +1591,15 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     private static final class LoanDisbursementDetailMapper implements RowMapper<DisbursementData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        LoanDisbursementDetailMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String schema() {
-            return "dd.id as id,dd.expected_disburse_date as expectedDisbursementdate, dd.disbursedon_date as actualDisbursementdate,dd.principal as principal,dd.net_disbursal_amount as netDisbursalAmount,sum(lc.amount) chargeAmount, lc.amount_waived_derived waivedAmount,group_concat(lc.id) loanChargeId "
+            return "dd.id as id,dd.expected_disburse_date as expectedDisbursementdate, dd.disbursedon_date as actualDisbursementdate,dd.principal as principal,dd.net_disbursal_amount as netDisbursalAmount,sum(lc.amount) chargeAmount, lc.amount_waived_derived waivedAmount, "
+                    + sqlGenerator.groupConcat("lc.id") + " loanChargeId "
                     + "from m_loan l inner join m_loan_disbursement_detail dd on dd.loan_id = l.id left join m_loan_tranche_disbursement_charge tdc on tdc.disbursement_detail_id=dd.id "
                     + "left join m_loan_charge lc on  lc.id=tdc.loan_charge_id and lc.is_active=true";
         }
@@ -1596,7 +1626,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     @Override
     public DisbursementData retrieveLoanDisbursementDetail(Long loanId, Long disbursementId) {
-        final LoanDisbursementDetailMapper rm = new LoanDisbursementDetailMapper();
+        final LoanDisbursementDetailMapper rm = new LoanDisbursementDetailMapper(sqlGenerator);
         final String sql = "select " + rm.schema() + " where dd.loan_id=? and dd.id=? group by dd.id, lc.amount_waived_derived";
         return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { loanId, disbursementId });
     }
@@ -1642,7 +1672,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
                 .append(" and (((ls.fee_charges_amount <> COALESCE(ls.accrual_fee_charges_derived, 0))")
                 .append(" or ( ls.penalty_charges_amount <> COALESCE(ls.accrual_penalty_charges_derived, 0))")
                 .append(" or ( ls.interest_amount <> COALESCE(ls.accrual_interest_derived, 0)))")
-                .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=false and ls.duedate <= CURDATE()) ");
+                .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and loan.is_npa=false and ls.duedate <= "
+                        + sqlGenerator.currentDate() + ") ");
         if (organisationStartDate != null) {
             sqlBuilder.append(" and ls.duedate > :organisationstartdate ");
         }
@@ -1662,27 +1693,26 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
         LoanSchedulePeriodicAccrualMapper mapper = new LoanSchedulePeriodicAccrualMapper();
         Date organisationStartDate = this.configurationDomainService.retrieveOrganisationStartDate();
+        String formattedTillDate = formatter.format(tillDate);
         final StringBuilder sqlBuilder = new StringBuilder(400);
         sqlBuilder.append("select ").append(mapper.schema()).append(
                 " where  (recaldet.is_compounding_to_be_posted_as_transaction is null or recaldet.is_compounding_to_be_posted_as_transaction = false) ")
                 .append(" and (((ls.fee_charges_amount <> COALESCE(ls.accrual_fee_charges_derived, 0))")
                 .append(" or (ls.penalty_charges_amount <> COALESCE(ls.accrual_penalty_charges_derived, 0))")
                 .append(" or (ls.interest_amount <> COALESCE(ls.accrual_interest_derived, 0)))")
-                .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and (loan.closedon_date <= :tilldate"
-                        + " or loan.closedon_date is null)")
-                .append(" and loan.is_npa=false and (ls.duedate <= :tilldate or (ls.duedate > :tilldate"
-                        + " and ls.fromdate < :tilldate))) ");
+                .append(" and loan.loan_status_id=:active and mpl.accounting_type=:type and (loan.closedon_date <= '" + formattedTillDate
+                        + "' or loan.closedon_date is null)")
+                .append(" and loan.is_npa=false and (ls.duedate <= '" + formattedTillDate + "' or (ls.duedate > '" + formattedTillDate
+                        + "' and ls.fromdate < '" + formattedTillDate + "'))) ");
         if (organisationStartDate != null) {
-            sqlBuilder.append(" and ls.duedate > :organisationstartdate ");
+            String formattedOrganizationStartDate = formatter
+                    .format(LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant()));
+            sqlBuilder.append(" and ls.duedate > '" + formattedOrganizationStartDate + "' ");
         }
         sqlBuilder.append(" order by loan.id,ls.duedate ");
         Map<String, Object> paramMap = new HashMap<>(4);
         paramMap.put("active", LoanStatus.ACTIVE.getValue());
         paramMap.put("type", AccountingRuleType.ACCRUAL_PERIODIC.getValue());
-        paramMap.put("tilldate", formatter.format(tillDate));
-        paramMap.put("organisationstartdate",
-                (organisationStartDate == null) ? formatter.format(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()))
-                        : formatter.format(LocalDate.ofInstant(organisationStartDate.toInstant(), DateUtils.getDateTimeZoneOfTenant())));
 
         return this.namedParameterJdbcTemplate.query(sqlBuilder.toString(), paramMap, mapper);
     }
@@ -1879,6 +1909,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     @Override
     public List<Long> fetchLoansForInterestRecalculation(Integer pageSize, Long maxLoanIdInList, String officeHierarchy) {
+        String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
+        // will look only for yesterday modified rates
+        String yesterday = formatter.format(DateUtils.getLocalDateOfTenant().minusDays(1));
         StringBuilder sqlBuilder = new StringBuilder();
         sqlBuilder.append("SELECT ml.id FROM m_loan ml ");
         sqlBuilder.append(" left join m_client mc on mc.id = ml.client_id ");
@@ -1893,19 +1926,20 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         sqlBuilder.append(" left join m_loan_reschedule_request lrr on lrr.loan_id = ml.id");
         // this is to identify the applicable rates when base rate is changed
         sqlBuilder.append(" left join  m_floating_rates bfr on  bfr.is_base_lending_rate = true");
-        sqlBuilder.append(" left join  m_floating_rates_periods bfrp on  bfr.id = bfrp.floating_rates_id and bfrp.created_date >= ?");
+        sqlBuilder.append(" left join  m_floating_rates_periods bfrp on  bfr.id = bfrp.floating_rates_id and bfrp.created_date >= '"
+                + yesterday + "'");
         sqlBuilder.append(" WHERE ml.loan_status_id = ? ");
         sqlBuilder.append(" and ml.is_npa = false ");
         sqlBuilder.append(" and ((");
         sqlBuilder.append("ml.interest_recalculation_enabled = true ");
-        sqlBuilder.append(" and (ml.interest_recalcualated_on is null or ml.interest_recalcualated_on <> ?)");
+        sqlBuilder.append(" and (ml.interest_recalcualated_on is null or ml.interest_recalcualated_on <> '" + currentdate + "')");
         sqlBuilder.append(" and ((");
         sqlBuilder.append(" mr.completed_derived is false ");
-        sqlBuilder.append(" and mr.duedate < ? )");
-        sqlBuilder.append(" or dd.expected_disburse_date < ? )) ");
+        sqlBuilder.append(" and mr.duedate < '" + currentdate + "' )");
+        sqlBuilder.append(" or dd.expected_disburse_date < '" + currentdate + "' )) ");
         sqlBuilder.append(" or (");
         sqlBuilder.append(" fr.is_active = true and  frp.is_active = true");
-        sqlBuilder.append(" and (frp.created_date >= ?  or ");
+        sqlBuilder.append(" and (frp.created_date >= '" + yesterday + "'  or ");
         sqlBuilder
                 .append("(bfrp.id is not null and frp.is_differential_to_base_lending_rate = true and frp.from_date >= bfrp.from_date)) ");
         sqlBuilder.append("and lrr.loan_id is null");
@@ -1914,12 +1948,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
         sqlBuilder.append(" group by ml.id ");
         sqlBuilder.append(" limit ? ");
         try {
-            String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
-            // will look only for yesterday modified rates
-            String yesterday = formatter.format(DateUtils.getLocalDateOfTenant().minusDays(1));
             return Collections.synchronizedList(this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class,
-                    new Object[] { yesterday, LoanStatus.ACTIVE.getValue(), currentdate, currentdate, currentdate, yesterday,
-                            maxLoanIdInList, officeHierarchy, pageSize }));
+                    new Object[] { LoanStatus.ACTIVE.getValue(), maxLoanIdInList, officeHierarchy, pageSize }));
         } catch (final EmptyResultDataAccessException e) {
             return null;
         }
@@ -1929,7 +1959,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
     public Collection<LoanTransactionData> retrieveWaiverLoanTransactions(final Long loanId) {
         try {
 
-            final LoanTransactionDerivedComponentMapper rm = new LoanTransactionDerivedComponentMapper();
+            final LoanTransactionDerivedComponentMapper rm = new LoanTransactionDerivedComponentMapper(sqlGenerator);
 
             final String sql = "select " + rm.schema()
                     + " where tr.loan_id = ? and tr.transaction_type_enum = ? and tr.is_reversed=false order by tr.transaction_date ASC,id ";
@@ -1947,10 +1977,16 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     private static final class LoanTransactionDerivedComponentMapper implements RowMapper<LoanTransactionData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        LoanTransactionDerivedComponentMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String schema() {
 
-            return " tr.id as id, tr.transaction_type_enum as transactionType, tr.transaction_date as `date`, tr.amount as total, "
-                    + " tr.principal_portion_derived as principal, tr.interest_portion_derived as interest, "
+            return " tr.id as id, tr.transaction_type_enum as transactionType, tr.transaction_date as " + sqlGenerator.escape("date")
+                    + ", tr.amount as total, " + " tr.principal_portion_derived as principal, tr.interest_portion_derived as interest, "
                     + " tr.fee_charges_portion_derived as fees, tr.penalty_charges_portion_derived as penalties, "
                     + " tr.overpayment_portion_derived as overpayment, tr.outstanding_loan_balance_derived as outstandingLoanBalance, "
                     + " tr.unrecognized_income_portion as unrecognizedIncome " + " from m_loan_transaction tr ";
@@ -2076,7 +2112,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
                     + " + SUM(COALESCE(mr.interest_completed_derived, 0)) " + " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
                     + " + SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) as total_in_advance_derived "
                     + " from m_loan ml INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id "
-                    + " where ml.id=? and  mr.duedate >= CURDATE() group by ml.id having "
+                    + " where ml.id=? and  mr.duedate >= " + sqlGenerator.currentDate() + " group by ml.id having "
                     + " (SUM(COALESCE(mr.principal_completed_derived, 0))  " + " + SUM(COALESCE(mr.interest_completed_derived, 0)) "
                     + " + SUM(COALESCE(mr.fee_charges_completed_derived, 0)) "
                     + "+  SUM(COALESCE(mr.penalty_charges_completed_derived, 0))) > 0";
@@ -2158,6 +2194,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     @Override
     public Collection<Long> retrieveLoanIdsWithPendingIncomePostingTransactions() {
+        String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
         StringBuilder sqlBuilder = new StringBuilder().append(" select distinct loan.id ").append(" from m_loan as loan ").append(
                 " inner join m_loan_recalculation_details as recdet on (recdet.loan_id = loan.id and recdet.is_compounding_to_be_posted_as_transaction is not null and recdet.is_compounding_to_be_posted_as_transaction = true) ")
                 .append(" inner join m_loan_repayment_schedule as repsch on repsch.loan_id = loan.id ")
@@ -2165,10 +2202,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
                 .append(" left join m_loan_transaction as trans on (trans.is_reversed <> true and trans.transaction_type_enum = 19 and trans.loan_id = loan.id and trans.transaction_date = adddet.effective_date) ")
                 .append(" where loan.loan_status_id = 300 ").append(" and loan.is_npa = false ")
                 .append(" and adddet.effective_date is not null ").append(" and trans.transaction_date is null ")
-                .append(" and adddet.effective_date < ? ");
+                .append(" and adddet.effective_date < '" + currentdate + "' ");
         try {
-            String currentdate = formatter.format(DateUtils.getLocalDateOfTenant());
-            return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class, new Object[] { currentdate });
+            return this.jdbcTemplate.queryForList(sqlBuilder.toString(), Long.class);
         } catch (final EmptyResultDataAccessException e) {
             return null;
         }
@@ -2222,8 +2258,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
 
     private static final class RepaymentTransactionTemplateMapper implements RowMapper<LoanTransactionData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
         private CurrencyMapper currencyMapper = new CurrencyMapper();
 
+        RepaymentTransactionTemplateMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String schema() {
             StringBuilder sqlBuilder = new StringBuilder();
 
@@ -2238,12 +2279,13 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
             sqlBuilder.append(
                     "ls.penalty_charges_amount - coalesce(ls.penalty_charges_completed_derived,0) - coalesce(ls.penalty_charges_writtenoff_derived,0) - coalesce(ls.penalty_charges_waived_derived,0) as penaltyDue, ");
             sqlBuilder.append(
-                    "l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, l.net_disbursal_amount as netDisbursalAmount, rc.`name` as currencyName, ");
+                    "l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, l.net_disbursal_amount as netDisbursalAmount, rc."
+                            + sqlGenerator.escape("name") + " as currencyName, ");
             sqlBuilder.append("rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode ");
             sqlBuilder.append("FROM m_loan l ");
             sqlBuilder.append(
                     "LEFT JOIN m_loan_transaction tr ON tr.loan_id = l.id AND tr.transaction_type_enum = ? and tr.is_reversed = false ");
-            sqlBuilder.append("join m_currency rc on rc.`code` = l.currency_code ");
+            sqlBuilder.append("join m_currency rc on rc." + sqlGenerator.escape("code") + " = l.currency_code ");
             sqlBuilder.append("JOIN m_loan_repayment_schedule ls ON ls.loan_id = l.id AND ls.completed_derived = 0 ");
             sqlBuilder.append("join( ");
             sqlBuilder.append("(select min(ls.duedate) datedue,ls.loan_id from m_loan_repayment_schedule ls ");
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
index 29a9b47..f228311 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductReadPlatformServiceImpl.java
@@ -29,6 +29,7 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType;
 import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAccessUtil;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
@@ -58,17 +59,20 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
     private final JdbcTemplate jdbcTemplate;
     private final ChargeReadPlatformService chargeReadPlatformService;
     private final RateReadService rateReadService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final FineractEntityAccessUtil fineractEntityAccessUtil;
 
     @Autowired
     public LoanProductReadPlatformServiceImpl(final PlatformSecurityContext context,
             final ChargeReadPlatformService chargeReadPlatformService, final RoutingDataSource dataSource,
-            final FineractEntityAccessUtil fineractEntityAccessUtil, final RateReadService rateReadService) {
+            final FineractEntityAccessUtil fineractEntityAccessUtil, final RateReadService rateReadService,
+            DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.chargeReadPlatformService = chargeReadPlatformService;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.fineractEntityAccessUtil = fineractEntityAccessUtil;
         this.rateReadService = rateReadService;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -121,7 +125,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
 
         this.context.authenticatedUser();
 
-        final LoanProductLookupMapper rm = new LoanProductLookupMapper();
+        final LoanProductLookupMapper rm = new LoanProductLookupMapper(sqlGenerator);
 
         String sql = "select " + rm.schema();
 
@@ -143,7 +147,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
     public Collection<LoanProductData> retrieveAllLoanProductsForLookup(final boolean activeOnly) {
         this.context.authenticatedUser();
 
-        final LoanProductLookupMapper rm = new LoanProductLookupMapper();
+        final LoanProductLookupMapper rm = new LoanProductLookupMapper(sqlGenerator);
 
         String sql = "select ";
         if (activeOnly) {
@@ -479,12 +483,18 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
 
     private static final class LoanProductLookupMapper implements RowMapper<LoanProductData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        LoanProductLookupMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         public String schema() {
             return "lp.id as id, lp.name as name, lp.allow_multiple_disbursals as multiDisburseLoan from m_product_loan lp";
         }
 
         public String activeOnlySchema() {
-            return schema() + " where (close_date is null or close_date >= CURDATE())";
+            return schema() + " where (close_date is null or close_date >= " + sqlGenerator.currentDate() + ")";
         }
 
         public String productMixSchema() {
@@ -563,7 +573,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
 
         this.context.authenticatedUser();
 
-        final LoanProductLookupMapper rm = new LoanProductLookupMapper();
+        final LoanProductLookupMapper rm = new LoanProductLookupMapper(sqlGenerator);
 
         String sql = "Select " + rm.productMixSchema();
 
@@ -583,7 +593,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
 
         this.context.authenticatedUser();
 
-        final LoanProductLookupMapper rm = new LoanProductLookupMapper();
+        final LoanProductLookupMapper rm = new LoanProductLookupMapper(sqlGenerator);
 
         String sql = "Select " + rm.restrictedProductsSchema() + " where pm.product_id=? ";
         // Check if branch specific products are enabled. If yes, fetch only
@@ -612,7 +622,7 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
 
         this.context.authenticatedUser();
 
-        final LoanProductLookupMapper rm = new LoanProductLookupMapper();
+        final LoanProductLookupMapper rm = new LoanProductLookupMapper(sqlGenerator);
 
         String sql = "Select " + rm.schema() + " where ";
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/service/RepaymentWithPostDatedChecksReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/service/RepaymentWithPostDatedChecksReadPlatformServiceImpl.java
index 59ec854..b3f1607 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/service/RepaymentWithPostDatedChecksReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/repaymentwithpostdatedchecks/service/RepaymentWithPostDatedChecksReadPlatformServiceImpl.java
@@ -32,8 +32,10 @@ import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDat
 import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.exception.PostDatedCheckNotFoundException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
+@Transactional(readOnly = true)
 public class RepaymentWithPostDatedChecksReadPlatformServiceImpl implements RepaymentWithPostDatedChecksReadPlatformService {
 
     private final PostDatedChecksRepository postDatedChecksRepository;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java
index 1ecf513..318f54a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountInterestRateChartReadPlatformServiceImpl.java
@@ -31,6 +31,7 @@ import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformSer
 import org.apache.fineract.infrastructure.core.data.EnumOptionData;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.client.api.ClientApiConstants;
@@ -59,21 +60,24 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D
     private final PlatformSecurityContext context;
     private final JdbcTemplate jdbcTemplate;
     private final DepositAccountInterestRateChartMapper chartRowMapper = new DepositAccountInterestRateChartMapper();
-    private final DepositAccountInterestRateChartExtractor chartExtractor = new DepositAccountInterestRateChartExtractor();
+    private final DepositAccountInterestRateChartExtractor chartExtractor;
     private final InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService;
     private final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService;
     private final CodeValueReadPlatformService codeValueReadPlatformService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public DepositAccountInterestRateChartReadPlatformServiceImpl(PlatformSecurityContext context, final RoutingDataSource dataSource,
             InterestRateChartDropdownReadPlatformService chartDropdownReadPlatformService,
             final InterestIncentiveDropdownReadPlatformService interestIncentiveDropdownReadPlatformService,
-            final CodeValueReadPlatformService codeValueReadPlatformService) {
+            final CodeValueReadPlatformService codeValueReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.chartDropdownReadPlatformService = chartDropdownReadPlatformService;
         this.interestIncentiveDropdownReadPlatformService = interestIncentiveDropdownReadPlatformService;
         this.codeValueReadPlatformService = codeValueReadPlatformService;
+        this.sqlGenerator = sqlGenerator;
+        chartExtractor = new DepositAccountInterestRateChartExtractor(sqlGenerator);
     }
 
     @Override
@@ -194,7 +198,7 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D
             return this.schemaSql;
         }
 
-        private DepositAccountInterestRateChartExtractor() {
+        private DepositAccountInterestRateChartExtractor(DatabaseSpecificSQLGenerator sqlGenerator) {
             final StringBuilder sqlBuilder = new StringBuilder(400);
 
             sqlBuilder.append("irc.id as ircId, irc.name as ircName, irc.description as ircDescription,")
@@ -212,7 +216,7 @@ public class DepositAccountInterestRateChartReadPlatformServiceImpl implements D
                     .append("from ")
                     .append("m_savings_account_interest_rate_chart irc left join m_savings_account_interest_rate_slab ircd on irc.id=ircd.savings_account_interest_rate_chart_id ")
                     .append(" left join m_savings_interest_incentives  iri on iri.deposit_account_interest_rate_slab_id =ircd.id ")
-                    .append(" left join m_code_value code on code.id = iri.attribute_value ")
+                    .append(" left join m_code_value code on " + sqlGenerator.castChar("code.id") + " = iri.attribute_value ")
                     .append("left join m_currency curr on ircd.currency_code= curr.code ")
                     .append("left join m_savings_account sa on irc.savings_account_id=sa.id ");
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountOnHoldTransactionReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountOnHoldTransactionReadPlatformServiceImpl.java
index 082d97b..dbdf63c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountOnHoldTransactionReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountOnHoldTransactionReadPlatformServiceImpl.java
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.portfolio.savings.data.DepositAccountOnHoldTransactionData;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,16 +42,19 @@ import org.springframework.stereotype.Service;
 public class DepositAccountOnHoldTransactionReadPlatformServiceImpl implements DepositAccountOnHoldTransactionReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final ColumnValidator columnValidator;
-    private final PaginationHelper<DepositAccountOnHoldTransactionData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
     private final DepositAccountOnHoldTransactionsMapper mapper;
 
     @Autowired
-    public DepositAccountOnHoldTransactionReadPlatformServiceImpl(final RoutingDataSource dataSource,
-            final ColumnValidator columnValidator) {
+    public DepositAccountOnHoldTransactionReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
-        mapper = new DepositAccountOnHoldTransactionsMapper();
+        this.sqlGenerator = sqlGenerator;
+        this.mapper = new DepositAccountOnHoldTransactionsMapper();
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -58,7 +62,7 @@ public class DepositAccountOnHoldTransactionReadPlatformServiceImpl implements D
             SearchParameters searchParameters) {
         final StringBuilder sqlBuilder = new StringBuilder(200);
         List<Long> paramObj = new ArrayList<>(2);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.mapper.schema());
 
         sqlBuilder.append(" where tr.savings_account_id = ? ");
@@ -79,15 +83,16 @@ public class DepositAccountOnHoldTransactionReadPlatformServiceImpl implements D
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         final Object[] finalObjectArray = paramObj.toArray();
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray, this.mapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.mapper);
 
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
index 4018a7c..4047bb8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountReadPlatformServiceImpl.java
@@ -37,6 +37,7 @@ import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.staff.data.StaffData;
@@ -107,7 +108,8 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
     private final DepositAccountLookupMapper depositAccountLookupsRowMapper = new DepositAccountLookupMapper();
     private final DepositAccountForMaturityMapper depositAccountForMaturityRowMapper = new DepositAccountForMaturityMapper();
     private final PaginationParametersDataValidator paginationParametersDataValidator;
-    private final PaginationHelper<DepositAccountData> paginationHelper = new PaginationHelper<>();
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
+    private final PaginationHelper paginationHelper;
     private final SavingsAccountTransactionsMapper transactionsMapper;
     private final ClientReadPlatformService clientReadPlatformService;
     private final GroupReadPlatformService groupReadPlatformService;
@@ -137,11 +139,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
             final InterestRateChartReadPlatformService productChartReadPlatformService,
             final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
             final DropdownReadPlatformService dropdownReadPlatformService, final CalendarReadPlatformService calendarReadPlatformService,
-            PaymentTypeReadPlatformService paymentTypeReadPlatformService) {
+            PaymentTypeReadPlatformService paymentTypeReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.accountChartReadPlatformService = chartReadPlatformService;
         this.paginationParametersDataValidator = paginationParametersDataValidator;
+        this.sqlGenerator = sqlGenerator;
         this.transactionsMapper = new SavingsAccountTransactionsMapper();
         this.clientReadPlatformService = clientReadPlatformService;
         this.groupReadPlatformService = groupReadPlatformService;
@@ -156,6 +160,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
         this.dropdownReadPlatformService = dropdownReadPlatformService;
         this.calendarReadPlatformService = calendarReadPlatformService;
         this.paymentTypeReadPlatformService = paymentTypeReadPlatformService;
+        this.paginationHelper = paginationHelper;
     }
 
     @Override
@@ -191,15 +196,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
         }
 
         final StringBuilder sqlBuilder = new StringBuilder(400);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(depositAccountMapper.schema());
         sqlBuilder.append(" where sa.deposit_type_enum = ? ");
         sqlBuilder.append(paginationParameters.paginationSql());
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
-                new Object[] { depositAccountType.getValue() }, depositAccountMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), new Object[] { depositAccountType.getValue() },
+                depositAccountMapper);
     }
 
     @Override
@@ -222,11 +225,9 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
         sqlBuilder.append(this.depositAccountForMaturityRowMapper.schema());
         sqlBuilder.append(" WHERE da.deposit_type_enum in (?, ?) and da.status_enum = ?");
 
-        LocalDate today = DateUtils.getLocalDateOfTenant();
-
         return this.jdbcTemplate.query(sqlBuilder.toString(), this.depositAccountForMaturityRowMapper,
-                new Object[] { formatter.format(today), DepositAccountType.FIXED_DEPOSIT.getValue(),
-                        DepositAccountType.RECURRING_DEPOSIT.getValue(), SavingsAccountStatusType.ACTIVE.getValue() });
+                new Object[] { DepositAccountType.FIXED_DEPOSIT.getValue(), DepositAccountType.RECURRING_DEPOSIT.getValue(),
+                        SavingsAccountStatusType.ACTIVE.getValue() });
     }
 
     @Override
@@ -519,6 +520,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
 
     @Override
     public Collection<Map<String, Object>> retriveDataForRDScheduleCreation() {
+        String today = formatter.format(DateUtils.getLocalDateOfTenant());
         final StringBuilder sb = new StringBuilder(300);
         sb.append(" select rd.savings_account_id savingsId, rd.mandatory_recommended_deposit_amount as amount,");
         sb.append(" mc.recurrence as recurrence ,");
@@ -529,13 +531,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
         sb.append(" inner join m_deposit_account_recurring_detail rd on rd.savings_account_id = dat.savings_account_id ");
         sb.append(" inner join m_calendar_instance mci on mci.entity_type_enum = ? and mci.entity_id = dat.savings_account_id  ");
         sb.append(" inner join m_calendar mc  on mc.id = mci.calendar_id and mc.calendar_type_enum = ?");
-        sb.append(" inner join m_mandatory_savings_schedule ms on ms.savings_account_id = dat.savings_account_id and ms.duedate > ?");
+        sb.append(" inner join m_mandatory_savings_schedule ms on ms.savings_account_id = dat.savings_account_id and ms.duedate > '" + today
+                + "'");
         sb.append(" where dat.deposit_period is null");
         sb.append(" group by ms.savings_account_id, rd.mandatory_recommended_deposit_amount, mc.recurrence, rd.savings_account_id");
 
         return this.jdbcTemplate.queryForList(sb.toString(), SavingsAccountStatusType.ACTIVE.getValue(),
-                CalendarEntityType.SAVINGS.getValue(), CalendarType.COLLECTION.getValue(),
-                formatter.format(DateUtils.getLocalDateOfTenant()));
+                CalendarEntityType.SAVINGS.getValue(), CalendarType.COLLECTION.getValue());
     }
 
     private abstract static class DepositAccountMapper implements RowMapper<DepositAccountData> {
@@ -1383,22 +1385,20 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
 
     private static final class DepositAccountForMaturityMapper implements RowMapper<DepositAccountData> {
 
-        private final String schemaSql;
+        private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
-        DepositAccountForMaturityMapper() {
+        public String schema() {
+            LocalDate today = DateUtils.getLocalDateOfTenant();
+            String formattedToday = formatter.format(today);
             final StringBuilder sqlBuilder = new StringBuilder(200);
             sqlBuilder.append("da.id as id, ");
             sqlBuilder.append("da.account_no as accountNumber, ");
             sqlBuilder.append("da.deposit_type_enum as depositTypeId ");
             sqlBuilder.append("FROM m_savings_account da ");
             sqlBuilder.append("inner join m_deposit_account_term_and_preclosure dat on dat.savings_account_id = da.id ");
-            sqlBuilder.append("and dat.maturity_date is not null and dat.maturity_date <= ? ");
+            sqlBuilder.append("and dat.maturity_date is not null and dat.maturity_date <= '" + formattedToday + "' ");
 
-            this.schemaSql = sqlBuilder.toString();
-        }
-
-        public String schema() {
-            return this.schemaSql;
+            return sqlBuilder.toString();
         }
 
         @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
index 14504c9..1e5fca9 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java
@@ -40,6 +40,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
 import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
 import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
@@ -101,6 +102,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
     private final SavingsProductReadPlatformService savingsProductReadPlatformService;
     private final StaffReadPlatformService staffReadPlatformService;
     private final SavingsDropdownReadPlatformService dropdownReadPlatformService;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final ChargeReadPlatformService chargeReadPlatformService;
     private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
@@ -113,7 +115,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
     // private final SavingsAccountAnnualFeeMapper annualFeeMapper;
 
     // pagination
-    private final PaginationHelper<SavingsAccountData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
 
     private final EntityDatatableChecksReadService entityDatatableChecksReadService;
     private final ColumnValidator columnValidator;
@@ -126,7 +128,8 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             final StaffReadPlatformService staffReadPlatformService, final SavingsDropdownReadPlatformService dropdownReadPlatformService,
             final ChargeReadPlatformService chargeReadPlatformService,
             final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator,
-            final SavingsAccountAssembler savingAccountAssembler) {
+            final SavingsAccountAssembler savingAccountAssembler, PaginationHelper paginationHelper,
+            DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.clientReadPlatformService = clientReadPlatformService;
@@ -134,6 +137,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
         this.savingsProductReadPlatformService = savingProductReadPlatformService;
         this.staffReadPlatformService = staffReadPlatformService;
         this.dropdownReadPlatformService = dropdownReadPlatformService;
+        this.sqlGenerator = sqlGenerator;
         this.transactionTemplateMapper = new SavingsAccountTransactionTemplateMapper();
         this.transactionsMapper = new SavingsAccountTransactionsMapper();
         this.savingsAccountTransactionsForBatchMapper = new SavingsAccountTransactionsForBatchMapper();
@@ -142,6 +146,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
         this.chargeReadPlatformService = chargeReadPlatformService;
         this.entityDatatableChecksReadService = entityDatatableChecksReadService;
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
         this.savingAccountMapperForInterestPosting = new SavingAccountMapperForInterestPosting();
         this.savingAccountAssembler = savingAccountAssembler;
     }
@@ -184,7 +189,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
         final String hierarchySearchString = hierarchy + "%";
 
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(this.savingAccountMapper.schema());
 
         sqlBuilder.append(" join m_office o on o.id = c.office_id");
@@ -222,16 +227,16 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
             }
 
             if (searchParameters.isLimited()) {
-                sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+                sqlBuilder.append(" ");
                 if (searchParameters.isOffset()) {
-                    sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+                } else {
+                    sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
                 }
             }
         }
         final Object[] finalObjectArray = Arrays.copyOf(objectArray, arrayPos);
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), finalObjectArray,
-                this.savingAccountMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), finalObjectArray, this.savingAccountMapper);
     }
 
     @Override
@@ -271,7 +276,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
                     + "where (CASE WHEN sa.interest_posted_till_date is not null THEN tr.transaction_date >= sa.interest_posted_till_date ELSE tr.transaction_date >= sa.activatedon_date END) ";
         }
 
-        sql = sql + "and apm.product_type=2 and sa.interest_posted_till_date<" + java.sql.Date.valueOf(currentDate);
+        sql = sql + "and apm.product_type=2 and sa.interest_posted_till_date < '" + java.sql.Date.valueOf(currentDate) + "'";
         sql = sql + " order by sa.id, tr.transaction_date, tr.created_date, tr.id";
 
         List<SavingsAccountData> savingsAccountDataList = this.jdbcTemplate.query(sql, this.savingAccountMapperForInterestPosting,
@@ -1650,20 +1655,21 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
 
     @Override
     public List<Long> retrieveSavingsIdsPendingInactive(LocalDate tenantLocalDate) {
+        String formattedTenantLocalDate = formatter.format(tenantLocalDate);
         List<Long> ret = null;
         StringBuilder sql = new StringBuilder("select sa.id ");
         sql.append(" from m_savings_account as sa ");
-        sql.append(" inner join m_savings_product as sp on (sa.product_id = sp.id and sp.is_dormancy_tracking_active = 1) ");
+        sql.append(" inner join m_savings_product as sp on (sa.product_id = sp.id and sp.is_dormancy_tracking_active = true) ");
         sql.append(" where sa.status_enum = 300 ");
         sql.append(" and sa.sub_status_enum = 0 ");
-        sql.append(" and DATEDIFF(?,(select COALESCE(max(sat.transaction_date), sa.activatedon_date) ");
-        sql.append(" from m_savings_account_transaction as sat ");
-        sql.append(" where sat.is_reversed = false ");
-        sql.append(" and sat.transaction_type_enum in (1,2) ");
-        sql.append(" and sat.savings_account_id = sa.id)) >= sp.days_to_inactive ");
+        String compareDate = "(select COALESCE(max(sat.transaction_date), sa.activatedon_date) "
+                + "from m_savings_account_transaction as sat where sat.is_reversed = false"
+                + " and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)";
+        sql.append(" and ").append(sqlGenerator.dateDiff("'" + formattedTenantLocalDate + "'", compareDate))
+                .append(" >= sp.days_to_inactive ");
 
         try {
-            ret = this.jdbcTemplate.queryForList(sql.toString(), Long.class, new Object[] { formatter.format(tenantLocalDate) });
+            ret = this.jdbcTemplate.queryForList(sql.toString(), Long.class);
         } catch (EmptyResultDataAccessException e) {
             // ignore empty result scenario
         } catch (DataAccessException e) {
@@ -1675,20 +1681,20 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
 
     @Override
     public List<Long> retrieveSavingsIdsPendingDormant(LocalDate tenantLocalDate) {
+        String currentDate = formatter.format(tenantLocalDate);
         List<Long> ret = null;
         StringBuilder sql = new StringBuilder("select sa.id ");
         sql.append(" from m_savings_account as sa ");
-        sql.append(" inner join m_savings_product as sp on (sa.product_id = sp.id and sp.is_dormancy_tracking_active = 1) ");
+        sql.append(" inner join m_savings_product as sp on (sa.product_id = sp.id and sp.is_dormancy_tracking_active = true) ");
         sql.append(" where sa.status_enum = 300 ");
         sql.append(" and sa.sub_status_enum = 100 ");
-        sql.append(" and DATEDIFF(?,(select COALESCE(max(sat.transaction_date),sa.activatedon_date) ");
-        sql.append(" from m_savings_account_transaction as sat ");
-        sql.append(" where sat.is_reversed = false ");
-        sql.append(" and sat.transaction_type_enum in (1,2) ");
-        sql.append(" and sat.savings_account_id = sa.id)) >= sp.days_to_dormancy ");
+        sql.append(" and " + sqlGenerator.dateDiff("'" + currentDate + "'",
+                "(select COALESCE(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)")
+                + " ");
+        sql.append(" >= sp.days_to_dormancy ");
 
         try {
-            ret = this.jdbcTemplate.queryForList(sql.toString(), Long.class, new Object[] { formatter.format(tenantLocalDate) });
+            ret = this.jdbcTemplate.queryForList(sql.toString(), Long.class);
         } catch (EmptyResultDataAccessException e) {
             // ignore empty result scenario
         } catch (DataAccessException e) {
@@ -1706,11 +1712,10 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
         sql.append(" inner join m_savings_product as sp on (sa.product_id = sp.id and sp.is_dormancy_tracking_active = true) ");
         sql.append(" where sa.status_enum = 300 ");
         sql.append(" and sa.sub_status_enum = 200 ");
-        sql.append(" and DATEDIFF(?,(select COALESCE(max(sat.transaction_date),sa.activatedon_date) ");
-        sql.append(" from m_savings_account_transaction as sat ");
-        sql.append(" where sat.is_reversed = false ");
-        sql.append(" and sat.transaction_type_enum in (1,2) ");
-        sql.append(" and sat.savings_account_id = sa.id)) >= sp.days_to_escheat ");
+        sql.append(" and " + sqlGenerator.dateDiff("?",
+                "(select COALESCE(max(sat.transaction_date),sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.transaction_type_enum in (1,2) and sat.savings_account_id = sa.id)")
+                + " ");
+        sql.append(" >= sp.days_to_escheat ");
 
         try {
             ret = this.jdbcTemplate.queryForList(sql.toString(), Long.class, new Object[] { formatter.format(tenantLocalDate) });
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
index 3e0097e..b78a39b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularInterestPoster.java
@@ -108,6 +108,10 @@ public class SavingsSchedularInterestPoster implements Callable<Void> {
         this.tenant = tenant;
     }
 
+    public void setConfigurationDomainService(ConfigurationDomainService configurationDomainService) {
+        this.configurationDomainService = configurationDomainService;
+    }
+
     public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
         this.jdbcTemplate = jdbcTemplate;
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java
index e8d1b30..6793ad6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java
@@ -183,6 +183,7 @@ public class SavingsSchedularServiceImpl implements SavingsSchedularService {
             poster.setJdbcTemplate(jdbcTemplate);
             poster.setBackdatedTxnsAllowedTill(backdatedTxnsAllowedTill);
             poster.setTransactionTemplate(transactionTemplate);
+            poster.setConfigurationDomainService(configurationDomainService);
 
             posters.add(poster);
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java
index 155fb2a..e11a665 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountDividendReadPlatformServiceImpl.java
@@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountData;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData;
@@ -45,12 +46,16 @@ public class ShareAccountDividendReadPlatformServiceImpl implements ShareAccount
 
     private final JdbcTemplate jdbcTemplate;
     private final ColumnValidator columnValidator;
-    private final PaginationHelper<ShareAccountDividendData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
-    public ShareAccountDividendReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public ShareAccountDividendReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -71,7 +76,7 @@ public class ShareAccountDividendReadPlatformServiceImpl implements ShareAccount
     public Page<ShareAccountDividendData> retriveAll(final Long payoutDetailId, final SearchParameters searchParameters) {
         ShareAccountDividendMapper shareAccountDividendMapper = new ShareAccountDividendMapper();
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(shareAccountDividendMapper.schema());
         sqlBuilder.append(" where sadd.dividend_pay_out_id = ? ");
         List<Object> params = new ArrayList<>(2);
@@ -92,16 +97,16 @@ public class ShareAccountDividendReadPlatformServiceImpl implements ShareAccount
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] paramsObj = params.toArray();
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), paramsObj,
-                shareAccountDividendMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), paramsObj, shareAccountDividendMapper);
     }
 
     private static final class ShareAccountDividendMapper implements RowMapper<ShareAccountDividendData> {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
index 5b42f6a..a82cb18 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountReadPlatformServiceImpl.java
@@ -36,6 +36,7 @@ import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.accountdetails.data.ShareAccountSummaryData;
 import org.apache.fineract.portfolio.accounts.constants.AccountsApiConstants;
@@ -82,7 +83,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
     private final PurchasedSharesReadPlatformService purchasedSharesReadPlatformService;
     private final JdbcTemplate jdbcTemplate;
     private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-    private final PaginationHelper<AccountData> shareAccountDataPaginationHelper = new PaginationHelper<>();
+    private final PaginationHelper shareAccountDataPaginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public ShareAccountReadPlatformServiceImpl(final RoutingDataSource dataSource, final ApplicationContext applicationContext,
@@ -91,7 +93,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
             final ClientReadPlatformService clientReadPlatformService,
             final ShareAccountChargeReadPlatformService shareAccountChargeReadPlatformService,
-            final PurchasedSharesReadPlatformService purchasedSharesReadPlatformService) {
+            final PurchasedSharesReadPlatformService purchasedSharesReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.applicationContext = applicationContext;
         this.chargeReadPlatformService = chargeReadPlatformService;
@@ -100,7 +103,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
         this.clientReadPlatformService = clientReadPlatformService;
         this.shareAccountChargeReadPlatformService = shareAccountChargeReadPlatformService;
         this.purchasedSharesReadPlatformService = purchasedSharesReadPlatformService;
-
+        this.shareAccountDataPaginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -190,7 +194,7 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
         final Collection<ShareAccountTransactionData> purchasedShares = null;
         ShareAccountMapper mapper = new ShareAccountMapper(charges, purchasedShares);
         StringBuilder sqlBuilder = new StringBuilder();
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(mapper.schema());
         sqlBuilder.append(" where sa.status_enum = ? ");
         if (limit != null) {
@@ -200,10 +204,8 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
             sqlBuilder.append(" offset ").append(offSet);
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] whereClauseItemsitems = new Object[] { ShareAccountStatusType.ACTIVE.getValue() };
-        return this.shareAccountDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
-                whereClauseItemsitems, mapper);
+        return this.shareAccountDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), whereClauseItemsitems, mapper);
     }
 
     @Override
@@ -223,10 +225,10 @@ public class ShareAccountReadPlatformServiceImpl implements ShareAccountReadPlat
         params.add(id);
         params.add(ShareAccountStatusType.ACTIVE.getValue());
         if (fetchInActiveAccounts) {
+            String formattedStartDate = formatter.format(startDate);
             sb.append(" and (sa.status_enum = ? or (sa.status_enum = ? ");
-            sb.append(" and sa.closed_date >  ?)) ");
+            sb.append(" and sa.closed_date > '" + formattedStartDate + "')) ");
             params.add(ShareAccountStatusType.CLOSED.getValue());
-            params.add(formatter.format(startDate));
         } else {
             sb.append(" and sa.status_enum = ? ");
         }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductDividendReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductDividendReadPlatformServiceImpl.java
index e0fe776..26d8e0d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductDividendReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductDividendReadPlatformServiceImpl.java
@@ -31,6 +31,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.infrastructure.core.service.SearchParameters;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
 import org.apache.fineract.portfolio.shareaccounts.data.ShareAccountDividendData;
 import org.apache.fineract.portfolio.shareaccounts.service.SharesEnumerations;
@@ -46,12 +47,16 @@ public class ShareProductDividendReadPlatformServiceImpl implements ShareProduct
 
     private final JdbcTemplate jdbcTemplate;
     private final ColumnValidator columnValidator;
-    private final PaginationHelper<ShareProductDividendPayOutData> paginationHelper = new PaginationHelper<>();
+    private final PaginationHelper paginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
-    public ShareProductDividendReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator) {
+    public ShareProductDividendReadPlatformServiceImpl(final RoutingDataSource dataSource, final ColumnValidator columnValidator,
+            DatabaseSpecificSQLGenerator sqlGenerator, PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.columnValidator = columnValidator;
+        this.paginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -59,7 +64,7 @@ public class ShareProductDividendReadPlatformServiceImpl implements ShareProduct
             final SearchParameters searchParameters) {
         ShareProductDividendMapper shareProductDividendMapper = new ShareProductDividendMapper();
         final StringBuilder sqlBuilder = new StringBuilder(200);
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(shareProductDividendMapper.schema());
         sqlBuilder.append(" where sp.id = ? ");
         List<Object> params = new ArrayList<>(2);
@@ -79,16 +84,16 @@ public class ShareProductDividendReadPlatformServiceImpl implements ShareProduct
         }
 
         if (searchParameters.isLimited()) {
-            sqlBuilder.append(" limit ").append(searchParameters.getLimit());
+            sqlBuilder.append(" ");
             if (searchParameters.isOffset()) {
-                sqlBuilder.append(" offset ").append(searchParameters.getOffset());
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit(), searchParameters.getOffset()));
+            } else {
+                sqlBuilder.append(sqlGenerator.limit(searchParameters.getLimit()));
             }
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] paramsObj = params.toArray();
-        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), paramsObj,
-                shareProductDividendMapper);
+        return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), paramsObj, shareProductDividendMapper);
     }
 
     private static final class ShareProductDividendMapper implements RowMapper<ShareProductDividendPayOutData> {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
index b027805..5fdf261 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductReadPlatformServiceImpl.java
@@ -37,6 +37,7 @@ import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.Page;
 import org.apache.fineract.infrastructure.core.service.PaginationHelper;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformService;
 import org.apache.fineract.portfolio.charge.data.ChargeData;
@@ -62,20 +63,24 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
     private final ShareProductDropdownReadPlatformService shareProductDropdownReadPlatformService;
     private final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService;
     private final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService;
-    private final PaginationHelper<ProductData> shareProductDataPaginationHelper = new PaginationHelper<>();
+    private final PaginationHelper shareProductDataPaginationHelper;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
 
     @Autowired
     public ShareProductReadPlatformServiceImpl(final RoutingDataSource dataSource,
             final CurrencyReadPlatformService currencyReadPlatformService, final ChargeReadPlatformService chargeReadPlatformService,
             final ShareProductDropdownReadPlatformService shareProductDropdownReadPlatformService,
             final AccountingDropdownReadPlatformService accountingDropdownReadPlatformService,
-            final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService) {
+            final ProductToGLAccountMappingReadPlatformService accountMappingReadPlatformService, DatabaseSpecificSQLGenerator sqlGenerator,
+            PaginationHelper paginationHelper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.currencyReadPlatformService = currencyReadPlatformService;
         this.chargeReadPlatformService = chargeReadPlatformService;
         this.shareProductDropdownReadPlatformService = shareProductDropdownReadPlatformService;
         this.accountingDropdownReadPlatformService = accountingDropdownReadPlatformService;
         this.accountMappingReadPlatformService = accountMappingReadPlatformService;
+        this.shareProductDataPaginationHelper = paginationHelper;
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -84,7 +89,7 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
         final Collection<ChargeData> charges = null;
         ShareProductRowMapper mapper = new ShareProductRowMapper(shareMarketCollection, charges);
         StringBuilder sqlBuilder = new StringBuilder();
-        sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
+        sqlBuilder.append("select " + sqlGenerator.calcFoundRows() + " ");
         sqlBuilder.append(mapper.schema());
         if (limit != null) {
             sqlBuilder.append(" limit ").append(limit);
@@ -93,10 +98,8 @@ public class ShareProductReadPlatformServiceImpl implements ProductReadPlatformS
             sqlBuilder.append(" offset ").append(offSet);
         }
 
-        final String sqlCountRows = "SELECT FOUND_ROWS()";
         Object[] whereClauseItemsitems = new Object[] {};
-        return this.shareProductDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
-                whereClauseItemsitems, mapper);
+        return this.shareProductDataPaginationHelper.fetchPage(this.jdbcTemplate, sqlBuilder.toString(), whereClauseItemsitems, mapper);
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java
index 0ffec88..0279f95 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java
@@ -38,6 +38,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
 import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSourceServiceFactory;
 import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.core.service.database.DatabaseTypeResolver;
 import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
 import org.apache.fineract.infrastructure.jobs.domain.ScheduledJobDetail;
@@ -83,6 +84,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
     private final JobRegisterService jobRegisterService;
     private final ScheduledJobDetailRepository scheduledJobDetailsRepository;
     private final FineractProperties fineractProperties;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final DatabaseTypeResolver databaseTypeResolver;
 
     @Autowired
@@ -95,7 +97,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
             final ShareAccountSchedularService shareAccountSchedularService,
             final TrialBalanceRepositoryWrapper trialBalanceRepositoryWrapper, @Lazy final JobRegisterService jobRegisterService,
             final ScheduledJobDetailRepository scheduledJobDetailsRepository, final FineractProperties fineractProperties,
-            DatabaseTypeResolver databaseTypeResolver) {
+            DatabaseSpecificSQLGenerator sqlGenerator, DatabaseTypeResolver databaseTypeResolver) {
         this.dataSourceServiceFactory = dataSourceServiceFactory;
         this.savingsAccountWritePlatformService = savingsAccountWritePlatformService;
         this.savingsAccountChargeReadPlatformService = savingsAccountChargeReadPlatformService;
@@ -107,6 +109,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
         this.jobRegisterService = jobRegisterService;
         this.scheduledJobDetailsRepository = scheduledJobDetailsRepository;
         this.fineractProperties = fineractProperties;
+        this.sqlGenerator = sqlGenerator;
         this.databaseTypeResolver = databaseTypeResolver;
     }
 
@@ -219,7 +222,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
         updateSqlBuilder.append(" FROM m_loan ml ");
         updateSqlBuilder.append(" INNER JOIN m_loan_repayment_schedule mr on mr.loan_id = ml.id ");
         updateSqlBuilder.append(" WHERE ml.loan_status_id = 300 ");
-        updateSqlBuilder.append(" and mr.duedate >= CURDATE() ");
+        updateSqlBuilder.append(" and mr.duedate >= " + sqlGenerator.currentDate() + " ");
         updateSqlBuilder.append(" GROUP BY ml.id");
         updateSqlBuilder
                 .append(" HAVING (SUM(coalesce(mr.principal_completed_derived, 0)) + SUM(coalesce(mr.interest_completed_derived, 0)) +");
@@ -313,7 +316,8 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
         fromPart = " (select loan.id " + " FROM m_loan_arrears_aging laa" + " INNER JOIN  m_loan loan on laa.loan_id = loan.id "
                 + " INNER JOIN m_product_loan mpl on mpl.id = loan.product_id AND mpl.overdue_days_for_npa is not null "
                 + "WHERE loan.loan_status_id = 300 and " + "laa.overdue_since_date_derived < "
-                + "SUBDATE(CURDATE(),INTERVAL  COALESCE(mpl.overdue_days_for_npa, 0) day)" + " group by loan.id) as sl ";
+                + sqlGenerator.subDate(sqlGenerator.currentDate(), "COALESCE(mpl.overdue_days_for_npa, 0)", "day")
+                + " group by loan.id) as sl ";
         wherePart = " where ml.id=sl.id ";
         updateSqlBuilder.append("UPDATE m_loan as ml ");
         if (databaseTypeResolver.isMySQL()) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PasswordValidationPolicyReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PasswordValidationPolicyReadPlatformServiceImpl.java
index ee30fc5..b03af1f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PasswordValidationPolicyReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PasswordValidationPolicyReadPlatformServiceImpl.java
@@ -23,6 +23,7 @@ import java.sql.SQLException;
 import java.util.Collection;
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.useradministration.data.PasswordValidationPolicyData;
 import org.apache.fineract.useradministration.exception.PasswordValidationPolicyNotFoundException;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,12 +36,14 @@ import org.springframework.stereotype.Service;
 public class PasswordValidationPolicyReadPlatformServiceImpl implements PasswordValidationPolicyReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PasswordValidationPolicyMapper passwordValidationPolicyMapper;
 
     @Autowired
-    public PasswordValidationPolicyReadPlatformServiceImpl(final RoutingDataSource dataSource) {
+    public PasswordValidationPolicyReadPlatformServiceImpl(final RoutingDataSource dataSource, DatabaseSpecificSQLGenerator sqlGenerator) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
-        this.passwordValidationPolicyMapper = new PasswordValidationPolicyMapper();
+        this.sqlGenerator = sqlGenerator;
+        this.passwordValidationPolicyMapper = new PasswordValidationPolicyMapper(sqlGenerator);
     }
 
     @Override
@@ -62,6 +65,12 @@ public class PasswordValidationPolicyReadPlatformServiceImpl implements Password
 
     protected static final class PasswordValidationPolicyMapper implements RowMapper<PasswordValidationPolicyData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        public PasswordValidationPolicyMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         @Override
         public PasswordValidationPolicyData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
 
@@ -74,8 +83,8 @@ public class PasswordValidationPolicyReadPlatformServiceImpl implements Password
         }
 
         public String schema() {
-            return " pvp.id as id, pvp.active as active, pvp.description as description, pvp.`key` as `key`"
-                    + " from m_password_validation_policy pvp";
+            return " pvp.id as id, pvp.active as active, pvp.description as description, pvp." + sqlGenerator.escape("key") + " as "
+                    + sqlGenerator.escape("key") + "" + " from m_password_validation_policy pvp";
         }
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionReadPlatformServiceImpl.java
index fdb03ab..3e8d96e 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/PermissionReadPlatformServiceImpl.java
@@ -22,6 +22,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Collection;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
+import org.apache.fineract.infrastructure.core.service.database.DatabaseSpecificSQLGenerator;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.useradministration.data.PermissionData;
 import org.slf4j.Logger;
@@ -37,12 +38,15 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
     private static final Logger LOG = LoggerFactory.getLogger(PermissionReadPlatformServiceImpl.class);
 
     private final JdbcTemplate jdbcTemplate;
+    private final DatabaseSpecificSQLGenerator sqlGenerator;
     private final PlatformSecurityContext context;
 
     @Autowired
-    public PermissionReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
+    public PermissionReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
+            DatabaseSpecificSQLGenerator sqlGenerator) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
+        this.sqlGenerator = sqlGenerator;
     }
 
     @Override
@@ -50,7 +54,7 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
 
         this.context.authenticatedUser();
 
-        final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper();
+        final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(sqlGenerator);
         final String sql = mapper.permissionSchema();
         LOG.info("retrieveAllPermissions: {}", sql);
         return this.jdbcTemplate.query(sql, mapper, new Object[] {});
@@ -61,7 +65,7 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
 
         this.context.authenticatedUser();
 
-        final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper();
+        final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(sqlGenerator);
         final String sql = mapper.makerCheckerablePermissionSchema();
         LOG.info("retrieveAllMakerCheckerablePermissions: {}", sql);
 
@@ -71,7 +75,7 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
     @Override
     public Collection<PermissionData> retrieveAllRolePermissions(final Long roleId) {
 
-        final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper();
+        final PermissionUsageDataMapper mapper = new PermissionUsageDataMapper(sqlGenerator);
         final String sql = mapper.rolePermissionSchema();
         LOG.info("retrieveAllRolePermissions: {}", sql);
 
@@ -80,6 +84,12 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
 
     private static final class PermissionUsageDataMapper implements RowMapper<PermissionData> {
 
+        private final DatabaseSpecificSQLGenerator sqlGenerator;
+
+        PermissionUsageDataMapper(DatabaseSpecificSQLGenerator sqlGenerator) {
+            this.sqlGenerator = sqlGenerator;
+        }
+
         @Override
         public PermissionData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
 
@@ -106,7 +116,8 @@ public class PermissionReadPlatformServiceImpl implements PermissionReadPlatform
              */
 
             return "select p.grouping, p.code, p.entity_name as entityName, p.action_name as actionName, p.can_maker_checker as selected"
-                    + " from m_permission p " + " where `grouping` != 'special' and code not like 'READ_%' and code not like '%\\_CHECKER'"
+                    + " from m_permission p " + " where " + sqlGenerator.escape("grouping")
+                    + " != 'special' and code not like 'READ_%' and code not like '%\\_CHECKER'"
                     + " order by p.grouping, coalesce(entity_name, ''), p.code";
         }
 
diff --git a/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml b/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml
index 7e5cd0f..5bc9e3c 100644
--- a/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml
+++ b/fineract-provider/src/main/resources/db/changelog/db.changelog-master.xml
@@ -23,6 +23,7 @@
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
     <property name="current_date" value="CURDATE()" context="mysql"/>
+    <property name="current_date" value="CURRENT_DATE" context="postgresql"/>
     <property name="current_datetime" value="NOW()"/>
     <include file="tenant-store/initial-switch-changelog-tenant-store.xml" relativeToChangelogFile="true" context="tenant_store_db AND initial_switch"/>
     <include file="tenant-store/changelog-tenant-store.xml" relativeToChangelogFile="true" context="tenant_store_db AND !initial_switch"/>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml b/fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml
index 05449fa..ae142fd 100644
--- a/fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml
+++ b/fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml
@@ -22,6 +22,5 @@
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
-    <!-- An example how to include upcoming changes -->
-    <!-- <include file="parts/0003_upcoming_change.xml" relativeToChangelogFile="true"/> -->
+     <include file="parts/0003_reset_postgresql_sequences.xml" relativeToChangelogFile="true"/>
 </databaseChangeLog>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml b/fineract-provider/src/main/resources/db/changelog/tenant-store/parts/0003_reset_postgresql_sequences.xml
similarity index 73%
copy from fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml
copy to fineract-provider/src/main/resources/db/changelog/tenant-store/parts/0003_reset_postgresql_sequences.xml
index 05449fa..b2ea722 100644
--- a/fineract-provider/src/main/resources/db/changelog/tenant-store/changelog-tenant-store.xml
+++ b/fineract-provider/src/main/resources/db/changelog/tenant-store/parts/0003_reset_postgresql_sequences.xml
@@ -22,6 +22,11 @@
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
-    <!-- An example how to include upcoming changes -->
-    <!-- <include file="parts/0003_upcoming_change.xml" relativeToChangelogFile="true"/> -->
+    <changeSet author="fineract" id="1-postgresql" context="postgresql">
+        <sql>
+            SELECT SETVAL('tenant_server_connections_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM tenant_server_connections;
+            SELECT SETVAL('tenants_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM tenants;
+            SELECT SETVAL('timezones_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM timezones;
+        </sql>
+    </changeSet>
 </databaseChangeLog>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 05449fa..0248acf 100644
--- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -22,6 +22,6 @@
 <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
-    <!-- An example how to include upcoming changes -->
-    <!-- <include file="parts/0003_upcoming_change.xml" relativeToChangelogFile="true"/> -->
+    <include file="parts/0003_postgresql_specific_initial_data.xml" relativeToChangelogFile="true"/>
+    <include file="parts/0004_camelcase_column_renaming.xml" relativeToChangelogFile="true"/>
 </databaseChangeLog>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0003_postgresql_specific_initial_data.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0003_postgresql_specific_initial_data.xml
new file mode 100644
index 0000000..96e19eb
--- /dev/null
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0003_postgresql_specific_initial_data.xml
@@ -0,0 +1,1972 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License. You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied. See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
+    <changeSet author="fineract" id="1-postgresql" context="postgresql">
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1"/>
+            <column name="parameter_name" value="startDateSelect"/>
+            <column name="parameter_variable" value="startDate"/>
+            <column name="parameter_label" value="startDate"/>
+            <column name="parameter_displayType" value="date"/>
+            <column name="parameter_FormatType" value="date"/>
+            <column name="parameter_default" value="today"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="2"/>
+            <column name="parameter_name" value="endDateSelect"/>
+            <column name="parameter_variable" value="endDate"/>
+            <column name="parameter_label" value="endDate"/>
+            <column name="parameter_displayType" value="date"/>
+            <column name="parameter_FormatType" value="date"/>
+            <column name="parameter_default" value="today"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="3"/>
+            <column name="parameter_name" value="obligDateTypeSelect"/>
+            <column name="parameter_variable" value="obligDateType"/>
+            <column name="parameter_label" value="obligDateType"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select * from  (select 1 as id, 'Closed' AS name union all select 2, 'Disbursal' ) x  order by x.id"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="5"/>
+            <column name="parameter_name" value="OfficeIdSelectOne"/>
+            <column name="parameter_variable" value="officeId"/>
+            <column name="parameter_label" value="Office"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne" value="Y"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select id, concat(substring('........................................', 1,        ((LENGTH(hierarchy) - LENGTH(REPLACE(hierarchy, '.', '')) - 1) * 4)),      name) as tc  from m_office  where hierarchy like concat('${currentUserHierarchy}', '%')  order by hierarchy"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="6"/>
+            <column name="parameter_name" value="loanOfficerIdSelectAll"/>
+            <column name="parameter_variable" value="loanOfficerId"/>
+            <column name="parameter_label" value="Loan Officer"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="(select lo.id, lo.display_name AS name   from m_office o join m_office ounder on ounder.hierarchy like concat(o.hierarchy, '%')  join m_staff lo on lo.office_id = ounder.id  where lo.is_loan_officer = true  and o.id = '${officeId}')  union all  (select -10, '-')  order by 2"/>
+            <column name="parent_id" valueNumeric="5"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="10"/>
+            <column name="parameter_name" value="currencyIdSelectAll"/>
+            <column name="parameter_variable" value="currencyId"/>
+            <column name="parameter_label" value="Currency"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select code, name  from m_organisation_currency  order by code"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="20"/>
+            <column name="parameter_name" value="fundIdSelectAll"/>
+            <column name="parameter_variable" value="fundId"/>
+            <column name="parameter_label" value="Fund"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="(select id, name  from m_fund)  union all  (select -10, '-')  order by 2"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="25"/>
+            <column name="parameter_name" value="loanProductIdSelectAll"/>
+            <column name="parameter_variable" value="loanProductId"/>
+            <column name="parameter_label" value="Product"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql"
+                    value="select p.id, p.`name`&#13;&#10;from m_product_loan p&#13;&#10;where (p.currency_code = '${currencyId}' or '-1'= '${currencyId}')&#13;&#10;order by 2"/>
+            <column name="parent_id" valueNumeric="10"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="26"/>
+            <column name="parameter_name" value="loanPurposeIdSelectAll"/>
+            <column name="parameter_variable" value="loanPurposeId"/>
+            <column name="parameter_label" value="Loan Purpose"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select -10 as id, '-' as code_value  union all  select * from (select v.id, v.code_value  from m_code c  join m_code_value v on v.code_id = c.id  where c.code_name = 'loanPurpose'  order by v.order_position)  x"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="100"/>
+            <column name="parameter_name" value="parTypeSelect"/>
+            <column name="parameter_variable" value="parType"/>
+            <column name="parameter_label" value="parType"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select * from  (select 1 as id, 'Principal Only' AS name union all  select 2, 'Principal + Interest' union all select 3, 'Principal + Interest + Fees' union all  select 4, 'Principal + Interest + Fees + Penalties') x  order by x.id"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1001"/>
+            <column name="parameter_name" value="FullReportList"/>
+            <column name="parameter_variable"/>
+            <column name="parameter_label" value="n/a"/>
+            <column name="parameter_displayType" value="n/a"/>
+            <column name="parameter_FormatType" value="n/a"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special" value="Y"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="SELECT r.id  AS report_id, r.report_name, r.report_type, r.report_subtype, r.report_category, rp.id AS parameter_id, rp.report_parameter_name, p.parameter_name FROM   stretchy_report r LEFT JOIN stretchy_report_parameter rp ON rp.report_id = r.id LEFT JOIN stretchy_parameter p ON p.id = rp.parameter_id WHERE  r.use_report IS TRUE AND r.self_service_user_report = false AND EXISTS (SELECT 'f' FROM   m_appuser_role ur JOIN m_role rr ON rr.id = [...]
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1002"/>
+            <column name="parameter_name" value="FullParameterList"/>
+            <column name="parameter_variable"/>
+            <column name="parameter_label" value="n/a"/>
+            <column name="parameter_displayType" value="n/a"/>
+            <column name="parameter_FormatType" value="n/a"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special" value="Y"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select sp.parameter_name, sp.parameter_variable, sp.parameter_label, sp.&quot;parameter_display_type&quot;, sp.&quot;parameter_format_type&quot;, sp.parameter_default, sp.&quot;selectOne&quot;,  sp.&quot;selectAll&quot;, spp.parameter_name as parentParameterName from stretchy_parameter sp  left join stretchy_parameter spp on spp.id = sp.parent_id  where sp.special is null  and exists     (select 'f'    from stretchy_report sr    join stretc [...]
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1003"/>
+            <column name="parameter_name" value="reportCategoryList"/>
+            <column name="parameter_variable"/>
+            <column name="parameter_label" value="n/a"/>
+            <column name="parameter_displayType" value="n/a"/>
+            <column name="parameter_FormatType" value="n/a"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special" value="Y"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select  r.id as report_id, r.report_name, r.report_type, r.report_subtype, r.report_category,   rp.id as parameter_id, rp.report_parameter_name, p.parameter_name from stretchy_report r   left join stretchy_report_parameter rp on rp.report_id = r.id   left join stretchy_parameter p on p.id = rp.parameter_id   where r.report_category = '${reportCategory}'   and r.use_report is true and r.self_service_user_report = '${isSelfServiceUser}'     a [...]
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1004"/>
+            <column name="parameter_name" value="selectAccount"/>
+            <column name="parameter_variable" value="accountNo"/>
+            <column name="parameter_label" value="Enter Account No"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="string"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1005"/>
+            <column name="parameter_name" value="savingsProductIdSelectAll"/>
+            <column name="parameter_variable" value="savingsProductId"/>
+            <column name="parameter_label" value="Product"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select p.id, p.name  from m_savings_product p  order by 2"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1006"/>
+            <column name="parameter_name" value="transactionId"/>
+            <column name="parameter_variable" value="transactionId"/>
+            <column name="parameter_label" value="transactionId"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="string"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1007"/>
+            <column name="parameter_name" value="selectCenterId"/>
+            <column name="parameter_variable" value="centerId"/>
+            <column name="parameter_label" value="Enter Center Id"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="string"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1008"/>
+            <column name="parameter_name" value="SelectGLAccountNO"/>
+            <column name="parameter_variable" value="GLAccountNO"/>
+            <column name="parameter_label" value="GLAccountNO"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="0"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select id aid,name aname  from acc_gl_account"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1009"/>
+            <column name="parameter_name" value="asOnDate"/>
+            <column name="parameter_variable" value="asOn"/>
+            <column name="parameter_label" value="As On"/>
+            <column name="parameter_displayType" value="date"/>
+            <column name="parameter_FormatType" value="date"/>
+            <column name="parameter_default" value="today"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1010"/>
+            <column name="parameter_name" value="SavingsAccountSubStatus"/>
+            <column name="parameter_variable" value="subStatus"/>
+            <column name="parameter_label" value="SavingsAccountDormancyStatus"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="100"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql" value="select * from  (select 100 as id, 'Inactive' as name  union all  select 200 as id, 'Dormant' as  name union all   select 300 as id, 'Escheat' as name) x  order by x.id"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1011"/>
+            <column name="parameter_name" value="cycleXSelect"/>
+            <column name="parameter_variable" value="cycleX"/>
+            <column name="parameter_label" value="Cycle X Number"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1012"/>
+            <column name="parameter_name" value="cycleYSelect"/>
+            <column name="parameter_variable" value="cycleY"/>
+            <column name="parameter_label" value="Cycle Y Number"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1013"/>
+            <column name="parameter_name" value="fromXSelect"/>
+            <column name="parameter_variable" value="fromX"/>
+            <column name="parameter_label" value="From X Number"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1014"/>
+            <column name="parameter_name" value="toYSelect"/>
+            <column name="parameter_variable" value="toY"/>
+            <column name="parameter_label" value="To Y Number"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1015"/>
+            <column name="parameter_name" value="overdueXSelect"/>
+            <column name="parameter_variable" value="overdueX"/>
+            <column name="parameter_label" value="Overdue X Number"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1016"/>
+            <column name="parameter_name" value="overdueYSelect"/>
+            <column name="parameter_variable" value="overdueY"/>
+            <column name="parameter_label" value="Overdue Y Number"/>
+            <column name="parameter_displayType" value="text"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="n/a"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1017"/>
+            <column name="parameter_name" value="DefaultLoan"/>
+            <column name="parameter_variable" value="loanId"/>
+            <column name="parameter_label" value="Loan"/>
+            <column name="parameter_displayType" value="none"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="-1"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select ml.id  from m_loan ml  left join m_client mc on mc.id = ml.client_id  left join m_office mo on mo.id = mc.office_id  where mo.id = '${officeId}' or '${officeId}' = -1"/>
+            <column name="parent_id" valueNumeric="5"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1018"/>
+            <column name="parameter_name" value="DefaultClient"/>
+            <column name="parameter_variable" value="clientId"/>
+            <column name="parameter_label" value="Client"/>
+            <column name="parameter_displayType" value="none"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="-1"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select mc.id  from m_client mc  left join m_office mo on mc.office_id = mo.id  where mo.id = '${officeId}' or '${officeId}' = -1"/>
+            <column name="parent_id" valueNumeric="5"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1019"/>
+            <column name="parameter_name" value="DefaultGroup"/>
+            <column name="parameter_variable" value="groupId"/>
+            <column name="parameter_label" value="Group"/>
+            <column name="parameter_displayType" value="none"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="-1"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select mg.id  from m_group mg left join m_office mo on mg.office_id = mo.id where mo.id = '${officeId}' or '${officeId}' = -1"/>
+            <column name="parent_id" valueNumeric="5"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1020"/>
+            <column name="parameter_name" value="SelectLoanType"/>
+            <column name="parameter_variable" value="loanType"/>
+            <column name="parameter_label" value="Loan Type"/>
+            <column name="parameter_displayType" value="select"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="-1"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql" value="select enum_id as id, enum_value as value from r_enum_value where enum_name = 'loan_type_enum'"/>
+            <column name="parent_id"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1021"/>
+            <column name="parameter_name" value="DefaultSavings"/>
+            <column name="parameter_variable" value="savingsId"/>
+            <column name="parameter_label" value="Savings"/>
+            <column name="parameter_displayType" value="none"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="-1"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id" valueNumeric="5"/>
+        </insert>
+        <insert tableName="stretchy_parameter">
+            <column name="id" valueNumeric="1022"/>
+            <column name="parameter_name" value="DefaultSavingsTransactionId"/>
+            <column name="parameter_variable" value="savingsTransactionId"/>
+            <column name="parameter_label" value="Savings Transaction"/>
+            <column name="parameter_displayType" value="none"/>
+            <column name="parameter_FormatType" value="number"/>
+            <column name="parameter_default" value="-1"/>
+            <column name="special"/>
+            <column name="selectOne"/>
+            <column name="selectAll" value="Y"/>
+            <column name="parameter_sql"/>
+            <column name="parent_id" valueNumeric="5"/>
+        </insert>
+    </changeSet>
+    <changeSet author="fineract" id="2-postgresql" context="postgresql">
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="1"/>
+            <column name="report_name" value="Client Listing"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT Concat(REPEAT('..', (( Length(ounder.hierarchy) - Length( REPLACE(ounder.hierarchy, '.', '')) - 1 ))) , ounder.name)  AS &quot;Office/Branch&quot;, c.account_no  AS &quot;Client Account No.&quot;, c.display_name  AS name, r.enum_message_property AS &quot;Status&quot;, c.activation_date AS &quot;Activation&quot;, c.external_id AS &quot;External Id&quot; FROM   m_office o JOIN m_office ounder ON ounder.hierarchy LIKE Concat(o.hierarchy, ' [...]
+            <column name="description" value="Individual Client Report    Lists the small number of defined fields on the client table.  Would expect to copy this   report and add any 'one to one' additional data for specific tenant needs.    Can be run for any size MFI but you'd expect it only to be run within a branch for   larger ones.  Depending on how many columns are displayed, there is probably is a limit of about 20/50k clients returned for html display (export to excel doesn't   [...]
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="2"/>
+            <column name="report_name" value="Client Loans Listing"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, c.account_no AS &quot;Client Account No.&quot;, c.display_name AS name, r.enum_message_property  AS &quot;Client Status&quot;, lo.display_name  AS &quot;Loan Officer&quot;, l.account_no AS &quot;Loan Account No.&quot;, l.external_id  AS &quot;External Id&quot;, p.name AS loan, st.enum_message_ [...]
+            <column name="description" value="Individual Client Report    Pretty   wide report that lists the basic details of client loans.      Can be run for any size MFI but you'd expect it only to be run within a branch for larger ones.    There is probably is a limit of about 20/50k clients returned for html display (export to excel doesn't have that client browser/memory impact)."/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="5"/>
+            <column name="report_name" value="Loans Awaiting Disbursal"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, c.account_no AS &quot;Client Account No&quot;, c.display_name AS name, l.account_no AS &quot;Loan Account No.&quot;, pl.name  AS &quot;Product&quot;, f.name AS fund, Coalesce(cur.display_symbol, l.currency_code)  AS currency, l.principal_amount AS principal, l.term_frequency AS &quot;Term Freq [...]
+            <column name="description" value="Individual Client Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="6"/>
+            <column name="report_name" value="Loans Awaiting Disbursal Summary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, pl.name  AS &quot;Product&quot;, Coalesce(cur.display_symbol, l.currency_code)  AS currency, f.name AS fund, Sum(l.principal_amount)  AS principal FROM      m_office o JOIN      m_office ounder ON        ounder.hierarchy LIKE Concat(o.hierarchy, '%') AND       ounder.hierarchy LIKE Concat('${c [...]
+            <column name="description" value="Individual Client Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="7"/>
+            <column name="report_name" value="Loans Awaiting Disbursal Summary by Month"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, pl.name  AS &quot;Product&quot;, Coalesce(cur.display_symbol, l.currency_code)  AS &quot;currency&quot;, extract(year from l.expected_disbursedon_date) AS &quot;Year&quot;, to_char(l.expected_disbursedon_date, 'Month')  AS &quot;Month&quot;, Sum(l.principal_amount)  AS &quot;principal&quot; FR [...]
+            <column name="description" value="Individual Client Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="8"/>
+            <column name="report_name" value="Loans Pending Approval"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, c.account_no AS &quot;Client Account No.&quot;, c.display_name AS &quot;Client Name&quot;, Coalesce(cur.display_symbol, l.currency_code)  AS currency, pl.name  AS &quot;Product&quot;, l.account_no AS &quot;Loan Account No.&quot;, l.principal_amount AS &quot;Loan Amount&quot;, l.term_frequency  [...]
+            <column name="description" value="Individual Client Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="11"/>
+            <column name="report_name" value="Active Loans - Summary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT   Concat(REPEAT('..', ((Length(mo.hierarchy) - Length(REPLACE(mo.hierarchy, '.', '')) - 1))), mo.name) AS &quot;Office/Branch&quot;, x.currency AS currency, x.client_count AS &quot;No. of Clients&quot;, x.active_loan_count  AS &quot;No. Active                    Loans&quot;, x. loans_in_arrears_count  AS &quot;No. of Loans in                    Arrears&quot;, x.principal  AS &quot;Total Loans Disbursed&quot;, x.principal_repaid AS &quot [...]
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="12"/>
+            <column name="report_name" value="Active Loans - Details"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, l.currency_code)  AS currency, lo.display_name  AS &quot;Loan Officer&quot;, c.display_name AS &quot;Client&quot;, l.account_no AS &quot;Loan Account No.&quot;, pl.name  AS &quot;Product&quot;, f.name AS fund, l.principal_amount AS &quot;Loan Amount&quot;, l.annual [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="13"/>
+            <column name="report_name" value="Obligation Met Loans Details"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy ) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, l.currency_code) AS currency, c.account_no  AS &quot;Client Account No.&quot;, c.display_name  AS &quot;Client&quot;, l.account_no  AS &quot;Loan Account No.&quot;, pl.name AS &quot;Product&quot;, f.name  AS fund, l.principal_amount  AS &quot;Loan Amount&quot;, l. [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="14"/>
+            <column name="report_name" value="Obligation Met Loans Summary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy ) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, l.currency_code) AS currency, Count(DISTINCT(c.id)) AS &quot;No. of Clients&quot;, Count(DISTINCT(l.id)) AS &quot;No. of Loans&quot;, Sum(l.principal_amount) AS &quot;Total Loan Amount&quot;, Sum(l.principal_repaid_derived) AS &quot;Total Principal Repaid&quot;, S [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="15"/>
+            <column name="report_name" value="Portfolio at Risk"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT x.&quot;Currency&quot;, x.&quot;Principal Outstanding&quot;, x.&quot;Principal Overdue&quot;, x.&quot;Interest Outstanding&quot;, x.&quot;Interest Overdue&quot;, x.&quot;Fees Outstanding&quot;, x.&quot;Fees Overdue&quot;, x.&quot;Penalties Outstanding&quot;, x.&quot;Penalties Overdue&quot;, ( CASE WHEN ${parType} = 1 THEN cast(round((x.&quot;Principal Overdue&quot; * 100) / x.&quot;Principal Outstanding&quot;, 2) AS CHAR) WHEN ${parType [...]
+            <column name="description" value="Covers all loans.    For larger MFIs … we should add some derived fields on loan (or a 1:1 loan related table like mifos 2.x does)  Principle, Interest, Fees, Penalties Outstanding and Overdue (possibly waived and written off too)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="16"/>
+            <column name="report_name" value="Portfolio at Risk by Branch"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT   Concat(REPEAT('..', ((Length(mo.hierarchy ) - Length(REPLACE(mo.hierarchy, '.', '')) - 1))), mo.name) AS &quot;Office/Branch&quot;, x.&quot;Currency&quot;, x.&quot;Principal Outstanding&quot; , x.&quot;Principal Overdue&quot;, x.&quot;Interest Outstanding&quot;, x.&quot;Interest Overdue&quot;, x.&quot;Fees Outstanding&quot;, x.&quot;Fees Overdue&quot;, x.&quot;Penalties Outstanding&quot;, x.&quot;Penalties Overdue&quot;, ( CASE WHEN $ [...]
+            <column name="description" value="Covers all loans.    For larger MFIs … we should add some derived fields on loan (or a 1:1 loan related table like mifos 2.x does)  Principle, Interest, Fees, Penalties Outstanding and Overdue (possibly waived and written off too)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="20"/>
+            <column name="report_name" value="Funds Disbursed Between Dates Summary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Fund"/>
+            <column name="report_sql" value="SELECT    Coalesce(f.name, '-') AS fund, Coalesce(cur.display_symbol, l.currency_code) AS currency, Round(Sum(l.principal_amount), 4) AS disbursed_amount FROM      m_office ounder JOIN      m_client c ON        c.office_id = ounder.id JOIN      m_loan l ON        l.client_id = c.id JOIN      m_currency cur ON        cur.code = l.currency_code LEFT JOIN m_fund f ON        f.id = l.fund_id WHERE     disbursedon_date BETWEEN '${startDate}' AND '$ [...]
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="21"/>
+            <column name="report_name" value="Funds Disbursed Between Dates Summary by Office"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Fund"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(f.name, '-')  AS fund, Coalesce(cur.display_symbol, l.currency_code)  AS currency, Round(Sum(l.principal_amount), 4)  AS disbursed_amount FROM      m_office o JOIN      m_office ounder ON        ounder.hierarchy LIKE Concat(o.hierarchy, '%') AND       ounder.hierarchy LIKE Concat('${c [...]
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="48"/>
+            <column name="report_name" value="Balance Sheet"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Accounting"/>
+            <column name="report_sql"/>
+            <column name="description" value="Balance Sheet"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="49"/>
+            <column name="report_name" value="Income Statement"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Accounting"/>
+            <column name="report_sql"/>
+            <column name="description" value="Profit and Loss Statement"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="50"/>
+            <column name="report_name" value="Trial Balance"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Accounting"/>
+            <column name="report_sql"/>
+            <column name="description" value="Trial Balance Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="51"/>
+            <column name="report_name" value="Written-Off Loans"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, ml.currency_code) AS currency, c.account_no AS &quot;Client Account No.&quot;, c.display_name AS &quot;Client Name&quot;, ml.account_no  AS &quot;Loan Account No.&quot;, mpl.name AS &quot;Product Name&quot;, ml.disbursedon_date  AS &quot;Disbursed Date&quot;, lt.tr [...]
+            <column name="description" value="Individual Lending Report. Written Off Loans"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="52"/>
+            <column name="report_name" value="Aging Detail"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT     Concat(Repeat('..', ((Length(ounder.hierarchy) - Length(Replace(ounder.hierarchy , '.', '')) - 1))), ounder.NAME) AS &quot;Office/Branch&quot;, COALESCE(cur.display_symbol, ml.currency_code)  AS currency, mc.account_no AS &quot;Client Account No.&quot;, mc.display_name  AS &quot;Client Name&quot;, ml.account_no  AS &quot;Account Number&quot;, ml.principal_amount  AS &quot;Loan Amount&quot;, ml.principal_disbursed_derived  AS &quot;O [...]
+            <column name="description" value="Loan arrears aging (Weeks)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="53"/>
+            <column name="report_name" value="Aging Summary (Arrears in Weeks)"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Coalesce(periods.currencyname, periods.currency) AS currency, periods.period_no AS &quot;Weeks In Arrears (Up To)&quot;, coalesce(ars.loanid, 0) AS &quot;No Of Loans&quot;, coalesce(ars.principal,0.0) AS &quot;Original Principal&quot;, coalesce(ars.interest,0.0) AS &quot;Original Interest&quot;, coalesce(ars.prinpaid,0.0) AS &quot;Principal Paid&quot;, coalesce(ars.intpaid,0.0) AS &quot;Interest Paid&quot;, coalesce(ars.prinoverdue,0 [...]
+            <column name="description" value="Loan amount in arrears by branch"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="54"/>
+            <column name="report_name" value="Rescheduled Loans"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, ml.currency_code) AS currency, c.account_no AS &quot;Client Account No.&quot;, c.display_name AS &quot;Client Name&quot;, ml.account_no  AS &quot;Loan Account No.&quot;, mpl.name AS &quot;Product Name&quot;, ml.disbursedon_date  AS &quot;Disbursed Date&quot;, lt.tr [...]
+            <column name="description" value="Individual Lending Report. Rescheduled Loans.  The ability to reschedule (or mark that you have rescheduled the loan elsewhere) is a legacy of the older Mifos product.  Needed for migration."/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="55"/>
+            <column name="report_name" value="Active Loans Passed Final Maturity"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, l.currency_code)  AS currency, lo.display_name  AS &quot;Loan Officer&quot;, c.display_name AS &quot;Client&quot;, l.account_no AS &quot;Loan Account No.&quot;, pl.name  AS &quot;Product&quot;, f.name AS fund, l.principal_amount AS &quot;Loan Amount&quot;, l.annual [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="56"/>
+            <column name="report_name" value="Active Loans Passed Final Maturity Summary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT   Concat(REPEAT('..', ((Length(mo.hierarchy ) - Length(REPLACE(mo.hierarchy, '.', '')) - 1))), mo.name) AS &quot;Office/Branch&quot;, x.currency  AS currency, x.client_count  AS &quot;No. of Clients&quot;, x.active_loan_count AS &quot;No. Active                    Loans&quot;, x. arrears_loan_count AS &quot;No. of Loans in Arrears&quot;, x.principal AS &quot;Total Loans Disbursed&quot;, x.principal_repaid  AS &quot;Principal Repaid&quot [...]
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="57"/>
+            <column name="report_name" value="Active Loans in last installment"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(lastinstallment.hierarchy) - Length(REPLACE(lastinstallment.hierarchy, '.', '')) - 1))), lastinstallment.branch) AS &quot;Office/Branch&quot;, lastinstallment.currency, lastinstallment.&quot;Loan Officer&quot;, lastinstallment.&quot;Client Account No&quot;, lastinstallment.&quot;Client&quot;, lastinstallment.&quot;Loan Account No&quot;, lastinstallment.&quot;Product&quot;, lastinstallment.&quot;Fund&quot; [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="58"/>
+            <column name="report_name" value="Active Loans in last installment Summary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT   Concat(REPEAT('..', ((Length(mo.hierarchy ) - Length(REPLACE(mo.hierarchy, '.', '')) - 1))), mo.name) AS &quot;Office/Branch&quot;, x.currency  AS currency, x.client_count  AS &quot;No. of Clients&quot;, x.active_loan_count AS &quot;No. Active Loans&quot;, x. arrears_loan_count AS &quot;No. of Loans in Arrears&quot;, x.principal AS &quot;Total Loans Disbursed&quot;, x.principal_repaid  AS &quot;Principal Repaid&quot;, x.principal_outs [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="59"/>
+            <column name="report_name" value="Active Loans by Disbursal Period"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS &quot;Office/Branch&quot;, Coalesce(cur.display_symbol, l.currency_code)  AS currency, c.account_no AS &quot;Client Account No&quot;, c.display_name AS &quot;Client&quot;, l.account_no AS &quot;Loan Account No&quot;, pl.name  AS &quot;Product&quot;, f.name AS fund, l.principal_amount AS &quot;Loan Principal Amount&quot; [...]
+            <column name="description" value="Individual Client   Report"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="61"/>
+            <column name="report_name" value="Aging Summary (Arrears in Months)"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    Coalesce(periods.currencyname, periods.currency) AS currency, periods.period_no AS &quot;Days In Arrears&quot;, coalesce(ars.loanid, 0) AS &quot;No Of Loans&quot;, coalesce(ars.principal,0.0) AS &quot;Original Principal&quot;, coalesce(ars.interest,0.0) AS &quot;Original Interest&quot;, coalesce(ars.prinpaid,0.0) AS &quot;Principal Paid&quot;, coalesce(ars.intpaid,0.0) AS &quot;Interest Paid&quot;, coalesce(ars.prinoverdue,0.0) AS &q [...]
+            <column name="description" value="Loan amount in arrears by branch"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="91"/>
+            <column name="report_name" value="Loan Account Schedule"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="92"/>
+            <column name="report_name" value="Branch Expected Cash Flow"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="93"/>
+            <column name="report_name" value="Expected Payments By Date - Basic"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT    ounder.name AS &quot;Office&quot;, coalesce(ms.display_name,'-') AS &quot;Loan Officer&quot;, mc.account_no AS &quot;Client Account Number&quot;, mc.display_name AS &quot;Name&quot;, mp.name AS &quot;Product&quot;, ml.account_no AS &quot;Loan Account Number&quot;, mr.duedate AS &quot;Due Date&quot;, mr.installment AS &quot;Installment&quot;, cu.display_symbol AS &quot;Currency&quot;, mr.principal_amount - coalesce(mr.principal_comple [...]
+            <column name="description" value="Test"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="94"/>
+            <column name="report_name" value="Expected Payments By Date - Formatted"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="96"/>
+            <column name="report_name" value="GroupSummaryCounts"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT    x.* FROM      m_office o,&#10;          m_group g,&#10;          (&#10;                    SELECT    a.activeclients,&#10;                              (b.activeclientloans + c.activegrouploans) AS activeloans,&#10;                              b.activeclientloans,&#10;                              c.activegrouploans,&#10;                              (b.activeclientborrowers + c.activegroupborrowers) AS activeborrowers,&#10;         [...]
+            <column name="description" value="Utility query for getting group summary count details for a group_id"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="97"/>
+            <column name="report_name" value="GroupSummaryAmounts"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="&#10;SELECT    Coalesce(cur.display_symbol, l.currency_code)  AS currency,&#10;          Coalesce(Sum(l.principal_disbursed_derived),0) AS totaldisbursedamount,&#10;          Coalesce(Sum(l.principal_outstanding_derived),0) AS totalloanoutstandingamount,&#10;          Count(laa.loan_id) AS overdueloans,&#10;          Coalesce(Sum(laa.total_overdue_derived), 0)  AS totalloanoverdueamount&#10;FROM      m_group topgroup JOIN      m_office o ON    [...]
+            <column name="description" value="Utility query for getting group summary currency amount details for a group_id"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="106"/>
+            <column name="report_name" value="TxnRunningBalances"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Transaction"/>
+            <column name="report_sql" value="select DATE ${startDate} AS &quot;Transaction Date&quot;, 'Opening Balance' AS &quot;Transaction Type&quot;, null AS &quot;Office&quot;, null AS &quot;Loan Officer&quot;, null AS &quot;Loan Account No&quot;, null AS &quot;Loan Product&quot;, null AS &quot;Currency&quot;, null AS &quot;Client Account No&quot;, null AS &quot;Client&quot;, null AS &quot;Principal&quot;, null AS &quot;Interest&quot;, COALESCE(round(sum(CASE WHEN txn.transaction_ty [...]
+            <column name="description" value="Running Balance Txn report for Individual Lending.&#10;Suitable for small MFI's.  Larger could use it using the branch or other parameters.&#10;Basically, suck it and see if its quick enough for you out-of-te box or whether it needs performance work in your situation.&#10;"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="107"/>
+            <column name="report_name" value="FieldAgentStats"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="select COALESCE(cur.display_symbol, l.currency_code) as Currency, /*This query will return more than one entry if more than one currency is used */ count(distinct(c.id)) as activeClients, count(*) as activeLoans, sum(l.principal_disbursed_derived) as disbursedAmount, sum(l.principal_outstanding_derived) as loanOutstandingAmount, round((sum(l.principal_outstanding_derived) * 100) / sum(l.principal_disbursed_derived),2) as loanOutstandingPC, sum [...]
+            <column name="description" value="Field Agent Statistics"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="108"/>
+            <column name="report_name" value="FieldAgentPrograms"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="select pgm.id, pgm.display_name as name, sts.enum_message_property as status  from m_group pgm  join m_office o on o.id = pgm.office_id AND o.hierarchy like concat('${currentUserHierarchy}', '%') left join r_enum_value sts on sts.enum_name = 'status_enum' and sts.enum_id = pgm.status_enum  where pgm.staff_id = ${staffId}"/>
+            <column name="description" value="List of Field Agent Programs"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="109"/>
+            <column name="report_name" value="ProgramDetails"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="select l.id as loanId, l.account_no as loanAccountNo, c.id as clientId, c.account_no as clientAccountNo, pgm.display_name as programName,  (select count(*) from m_loan cy where cy.group_id = pgm.id and cy.client_id =c.id and cy.disbursedon_date &lt;= l.disbursedon_date) as loanCycleNo,  c.display_name as clientDisplayName, COALESCE(cur.display_symbol, l.currency_code) as Currency, COALESCE(l.principal_repaid_derived,0.0) as loanRepaidAmount, C [...]
+            <column name="description" value="List of Loans in a Program"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="110"/>
+            <column name="report_name" value="ChildrenStaffList"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="select s.id, s.display_name, s.firstname, s.lastname, s.organisational_role_enum,&#10;s.organisational_role_parent_staff_id,&#10;sp.display_name AS &quot;organisational_role_parent_staff_display_name&quot;&#10;from m_staff s&#10;join m_staff sp on s.organisational_role_parent_staff_id = sp.id&#10;where s.organisational_role_parent_staff_id = ${staffId}"/>
+            <column name="description" value="Get Next Level Down Staff"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="111"/>
+            <column name="report_name" value="CoordinatorStats"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="select COALESCE(cur.display_symbol, l.currency_code) as Currency, /*This query will return more than one entry if more than one currency is used */ count(distinct(c.id)) as activeClients, count(*) as activeLoans, sum(l.principal_disbursed_derived) as disbursedAmount, sum(l.principal_outstanding_derived) as loanOutstandingAmount, round((sum(l.principal_outstanding_derived) * 100) / sum(l.principal_disbursed_derived),2) as loanOutstandingPC, sum [...]
+            <column name="description" value="Coordinator Statistics"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="112"/>
+            <column name="report_name" value="BranchManagerStats"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="SELECT    Coalesce(cur.display_symbol, l.currency_code)  AS currency, Count(DISTINCT(c.id))  AS activeclients, Count(*) AS activeloans, Sum(l.principal_disbursed_derived) AS disbursedamount, Sum(l.principal_outstanding_derived) AS loanoutstandingamount, Round((Sum(l.principal_outstanding_derived) * 100) / Sum(l.principal_disbursed_derived),2) AS loanoutstandingpc, Sum(Coalesce(lpa.principal_in_advance_derived,0.0))  AS loanpaidinadvance, sum(  [...]
+            <column name="description" value="Branch Manager Statistics"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="113"/>
+            <column name="report_name" value="ProgramDirectorStats"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="SELECT    Coalesce(cur.display_symbol, l.currency_code) AS currency, /*This query will return more than one entry if more than one currency is used */ Count(DISTINCT(c.id))  AS activeclients, Count(*) AS activeloans, Sum(l.principal_disbursed_derived) AS disbursedamount, Sum(l.principal_outstanding_derived) AS loanoutstandingamount, Round((Sum(l.principal_outstanding_derived) * 100) / Sum(l.principal_disbursed_derived),2) AS loanoutstandingpc, [...]
+            <column name="description" value="Program DirectorStatistics"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="114"/>
+            <column name="report_name" value="ProgramStats"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Quipo"/>
+            <column name="report_sql" value="select COALESCE(cur.display_symbol, l.currency_code) as Currency, /*This query will return more than one entry if more than one currency is used */ count(distinct(c.id)) as activeClients, count(*) as activeLoans, sum(l.principal_disbursed_derived) as disbursedAmount, sum(l.principal_outstanding_derived) as loanOutstandingAmount, round((sum(l.principal_outstanding_derived) * 100) / sum(l.principal_disbursed_derived),2) as loanOutstandingPC, sum [...]
+            <column name="description" value="Program Statistics"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="115"/>
+            <column name="report_name" value="ClientSummary "/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT x.* FROM m_client c, m_office o, (SELECT a.loanCycle, a.activeLoans, b.lastLoanAmount, d.activeSavings, d.totalSavings FROM (SELECT COALESCE(MAX(l.loan_counter),0) AS loanCycle, COUNT(l.id) AS activeLoans FROM m_loan l WHERE l.loan_status_id=300 AND l.client_id=${clientId}) a, (SELECT count(l.id), COALESCE(l.principal_amount,0) AS lastLoanAmount FROM m_loan l WHERE l.client_id=${clientId} AND l.disbursedon_date = (SELECT COALESCE(MAX(di [...]
+            <column name="description" value="Utility query for getting the client summary details"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="116"/>
+            <column name="report_name" value="LoanCyclePerProduct"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT lp.name AS &quot;productName&quot;, MAX(l.loan_product_counter) AS &quot;loanProductCycle&quot; FROM m_loan l JOIN m_product_loan lp ON l.product_id=lp.id WHERE lp.include_in_borrower_cycle=true AND l.loan_product_counter IS NOT NULL AND l.client_id=${clientId} GROUP BY lp.id"/>
+            <column name="description" value="Utility query for getting the client loan cycle details"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="117"/>
+            <column name="report_name" value="GroupSavingSummary"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="select COALESCE(cur.display_symbol, sa.currency_code) as currency, count(sa.id) as totalSavingAccounts, COALESCE(sum(sa.account_balance_derived),0) as totalSavings from m_group topgroup join m_office o on o.id = topgroup.office_id and o.hierarchy like concat('${currentUserHierarchy}', '%') join m_group g on g.hierarchy like concat(topgroup.hierarchy, '%') join m_savings_account sa on sa.group_id = g.id left join m_currency cur on cur.code = sa [...]
+            <column name="description" value="Utility query for getting group or center saving summary details for a group_id"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="118"/>
+            <column name="report_name" value="Savings Transactions"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Savings"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="119"/>
+            <column name="report_name" value="Client Savings Summary"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Savings"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="120"/>
+            <column name="report_name" value="Active Loans - Details(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="121"/>
+            <column name="report_name" value="Active Loans - Summary(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="122"/>
+            <column name="report_name" value="Active Loans by Disbursal Period(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="123"/>
+            <column name="report_name" value="Active Loans in last installment Summary(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="124"/>
+            <column name="report_name" value="Active Loans in last installment(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="125"/>
+            <column name="report_name" value="Active Loans Passed Final Maturity Summary(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="126"/>
+            <column name="report_name" value="Active Loans Passed Final Maturity(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="127"/>
+            <column name="report_name" value="Aging Detail(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="128"/>
+            <column name="report_name" value="Aging Summary (Arrears in Months)(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="129"/>
+            <column name="report_name" value="Aging Summary (Arrears in Weeks)(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="130"/>
+            <column name="report_name" value="Client Listing(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="131"/>
+            <column name="report_name" value="Client Loans Listing(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="132"/>
+            <column name="report_name" value="Expected Payments By Date - Basic(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="133"/>
+            <column name="report_name" value="Funds Disbursed Between Dates Summary by Office(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Fund"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="134"/>
+            <column name="report_name" value="Funds Disbursed Between Dates Summary(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Fund"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="135"/>
+            <column name="report_name" value="Loans Awaiting Disbursal Summary by Month(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="136"/>
+            <column name="report_name" value="Loans Awaiting Disbursal Summary(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="137"/>
+            <column name="report_name" value="Loans Awaiting Disbursal(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="138"/>
+            <column name="report_name" value="Loans Pending Approval(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="139"/>
+            <column name="report_name" value="Obligation Met Loans Details(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="140"/>
+            <column name="report_name" value="Obligation Met Loans Summary(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="141"/>
+            <column name="report_name" value="Portfolio at Risk by Branch(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="142"/>
+            <column name="report_name" value="Portfolio at Risk(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="143"/>
+            <column name="report_name" value="Rescheduled Loans(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="144"/>
+            <column name="report_name" value="TxnRunningBalances(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Transaction"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="145"/>
+            <column name="report_name" value="Written-Off Loans(Pentaho)"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="146"/>
+            <column name="report_name" value="Client Saving Transactions"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Savings"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="147"/>
+            <column name="report_name" value="Client Loan Account Schedule"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="148"/>
+            <column name="report_name" value="GroupNamesByStaff"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value=""/>
+            <column name="report_sql" value="SELECT gr.id AS id, gr.display_name AS name FROM   m_group gr WHERE  gr.level_id=1 AND    gr.staff_id = ${staffId}"/>
+            <column name="description" value=""/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="149"/>
+            <column name="report_name" value="ClientTrendsByDay"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT COUNT(cl.id) AS count, cl.activation_date AS days FROM m_office of LEFT JOIN m_client cl on of.id = cl.office_id WHERE of.hierarchy like concat((select ino.hierarchy from m_office ino where ino.id = '${officeId}'),'%' ) AND (cl.activation_date BETWEEN (CURRENT_DATE - 12 * INTERVAL '1 day') AND NOW()) GROUP BY days"/>
+            <column name="description" value="Retrieves the number of clients joined in last 12 days"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="150"/>
+            <column name="report_name" value="ClientTrendsByWeek"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT COUNT(cl.id) AS count, EXTRACT(WEEK FROM cl.activation_date) AS Weeks FROM m_office of LEFT JOIN m_client cl on of.id = cl.office_id WHERE of.hierarchy like concat((select ino.hierarchy from m_office ino where ino.id = '${officeId}'),'%' ) AND (cl.activation_date BETWEEN (CURRENT_DATE - 12 * INTERVAL '1 WEEK') AND NOW()) GROUP BY Weeks"/>
+            <column name="description" value=""/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="151"/>
+            <column name="report_name" value="ClientTrendsByMonth"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT    Count(cl.id)  AS count, to_char(cl.activation_date, 'Month') AS &quot;Months&quot; FROM      m_office of LEFT JOIN m_client cl ON        of.id = cl.office_id WHERE     of.hierarchy LIKE Concat( ( SELECT ino.hierarchy FROM   m_office ino WHERE  ino.id = '${officeId}'),'%' ) AND       ( cl.activation_date BETWEEN (CURRENT_DATE - 12 * INTERVAL '1 MONTH') AND       DATE_TRUNC('day', now())) GROUP BY  &quot;Months&quot;"/>
+            <column name="description" value=""/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="152"/>
+            <column name="report_name" value="LoanTrendsByDay"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT COUNT(ln.id) AS lcount, ln.disbursedon_date AS days FROM m_office of LEFT JOIN m_client cl on of.id = cl.office_id LEFT JOIN m_loan ln on cl.id = ln.client_id WHERE of.hierarchy like concat((select ino.hierarchy from m_office ino where ino.id = '${officeId}'),'%' ) AND (ln.disbursedon_date BETWEEN (CURRENT_DATE - 12 * INTERVAL '1 day') AND NOW()) GROUP BY days"/>
+            <column name="description" value="Retrieves Number of loans disbursed for last 12 days"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="153"/>
+            <column name="report_name" value="LoanTrendsByWeek"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT COUNT(ln.id) AS lcount, EXTRACT(WEEK FROM ln.disbursedon_date) AS Weeks FROM m_office of LEFT JOIN m_client cl on of.id = cl.office_id LEFT JOIN m_loan ln on cl.id = ln.client_id WHERE of.hierarchy like concat((select ino.hierarchy from m_office ino where ino.id = '${officeId}'),'%' ) AND (ln.disbursedon_date BETWEEN (CURRENT_DATE - 12 * INTERVAL '1 week') AND NOW()) GROUP BY Weeks"/>
+            <column name="description" value=""/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="154"/>
+            <column name="report_name" value="LoanTrendsByMonth"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT COUNT(ln.id) AS lcount, EXTRACT(MONTH FROM ln.disbursedon_date) AS &quot;Months&quot; FROM m_office of LEFT JOIN m_client cl on of.id = cl.office_id LEFT JOIN m_loan ln on cl.id = ln.client_id WHERE of.hierarchy like concat((select ino.hierarchy from m_office ino where ino.id = '${officeId}'),'%' ) AND (ln.disbursedon_date BETWEEN (CURRENT_DATE - 12 * INTERVAL '1 month') AND NOW()) GROUP BY &quot;Months&quot;"/>
+            <column name="description" value=""/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="155"/>
+            <column name="report_name" value="Demand_Vs_Collection"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="select amount.AmountDue-amount.AmountPaid as AmountDue, amount.AmountPaid as AmountPaid from (SELECT (COALESCE(SUM(ls.principal_amount),0) - COALESCE(SUM(ls.principal_writtenoff_derived),0)  + COALESCE(SUM(ls.interest_amount),0) - COALESCE(SUM(ls.interest_writtenoff_derived),0)   - COALESCE(SUM(ls.interest_waived_derived),0) + COALESCE(SUM(ls.fee_charges_amount),0) - COALESCE(SUM(ls.fee_charges_writtenoff_derived),0) - COALESCE(SUM(ls.fee_char [...]
+            <column name="description" value="Demand Vs Collection"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="156"/>
+            <column name="report_name" value="Disbursal_Vs_Awaitingdisbursal"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype" value=""/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT awaitinddisbursal.amount-disbursedAmount.amount as amountToBeDisburse, disbursedAmount.amount as disbursedAmount FROM (SELECT COUNT(ln.id) AS noOfLoans, COALESCE(SUM(ln.principal_amount),0) AS amount FROM m_office of LEFT JOIN m_client cl ON cl.office_id = of.id LEFT JOIN m_loan ln ON cl.id = ln.client_id WHERE ln.expected_disbursedon_date = DATE_TRUNC('day', NOW()) AND (ln.loan_status_id=200 OR ln.loan_status_id=300) AND of.hierarchy l [...]
+            <column name="description" value="Disbursal_Vs_Awaitingdisbursal"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="157"/>
+            <column name="report_name" value="Savings Transaction Receipt"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="158"/>
+            <column name="report_name" value="Loan Transaction Receipt"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="159"/>
+            <column name="report_name" value="Staff Assignment History"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="160"/>
+            <column name="report_name" value="GeneralLedgerReport"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Accounting"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="161"/>
+            <column name="report_name" value="Active Loan Summary per Branch"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="162"/>
+            <column name="report_name" value="Balance Outstanding"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="163"/>
+            <column name="report_name" value="Collection Report"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="164"/>
+            <column name="report_name" value="Disbursal Report"/>
+            <column name="report_type" value="Pentaho"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql"/>
+            <column name="description"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="165"/>
+            <column name="report_name" value="Savings Accounts Dormancy Report"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="Savings"/>
+            <column name="report_sql" value="select cl.display_name AS &quot;Client Display Name&quot;, sa.account_no AS &quot;Account Number&quot;, cl.mobile_no AS &quot;Mobile Number&quot;, (select COALESCE(max(sat.transaction_date), sa.activatedon_date) from m_savings_account_transaction as sat where sat.is_reversed = false and sat.transaction_type_enum in (1, 2) and sat.savings_account_id = sa.id) AS &quot;Date of Last Activity&quot;, EXTRACT(DAY FROM (CURRENT_DATE - (select COALESCE [...]
+            <column name="description"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="166"/>
+            <column name="report_name" value="Active Clients"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstname, c.middlename AS middlename, c.lastname  AS lastname, c.display_name  AS fullname, c.mobile_no AS mobileno, Concat(REPEAT('..', ((Length(ounder.hierarchy) - Length( REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officename, o.id AS officenumber FROM  m_office o JOIN  m_office ounder ON ounder.hierarchy LIKE Concat(o.hierarchy, '%') JOIN  m_client c ON c.office_id = ounder.id LEFT JOIN r_ [...]
+            <column name="description" value="All clients with the status ‘Active’"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="167"/>
+            <column name="report_name" value="Prospective Clients"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstName, c.middlename AS middleName, c.lastname AS lastName, c.display_name AS fullName, c.mobile_no AS mobileNo, CONCAT(REPEAT('..', ((LENGTH(ounder.hierarchy) - LENGTH(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officeName, o.id AS officeNumber FROM m_office o JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarchy, '%') JOIN m_client c ON c.office_id = ounder.id LEFT JOIN r_enum_v [...]
+            <column name="description" value="All clients with the status ‘Active’ who have never had a loan before"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="168"/>
+            <column name="report_name" value="Active Loan Clients"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstName, c.middlename AS middleName, c.lastname AS lastName, c.display_name AS fullName, c.mobile_no AS mobileNo, l.principal_amount AS loanAmount, (COALESCE(l.principal_outstanding_derived, 0) + COALESCE(l.interest_outstanding_derived, 0) + COALESCE(l.fee_charges_outstanding_derived, 0) + COALESCE(l.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, l.principal_disbursed_derived AS loanDisbursed,  [...]
+            <column name="description" value="All clients with an outstanding loan between cycleX and cycleY days"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="169"/>
+            <column name="report_name" value="Loan in arrears"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT mc.id AS id, mc.firstname AS firstName, mc.middlename AS middleName, mc.lastname AS lastName, mc.display_name AS fullName, mc.mobile_no AS mobileNo, ml.principal_amount AS loanAmount, (COALESCE(ml.principal_outstanding_derived, 0) + COALESCE(ml.interest_outstanding_derived, 0) + COALESCE(ml.fee_charges_outstanding_derived, 0) + COALESCE(ml.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, ml.principal_disbursed_derived AS loa [...]
+            <column name="description" value="All clients with an outstanding loan in arrears between fromX and toY days"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="170"/>
+            <column name="report_name" value="Loan payments due"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT cl.id AS id, cl.firstname  AS firstName, cl.middlename  AS middleName, cl.lastname AS lastName, cl.display_name AS fullName, cl.mobile_no AS mobileNo, l.principal_amount AS loanAmount, of.id AS officeNumber, (COALESCE(l.principal_outstanding_derived, 0) + COALESCE(l.interest_outstanding_derived, 0) + COALESCE(l.fee_charges_outstanding_derived, 0) + COALESCE(l.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, l.principal_disbu [...]
+            <column name="description" value="All clients with an unpaid installment due on their loan between fromX and toY days"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="171"/>
+            <column name="report_name" value="Dormant Prospects"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id, CONCAT(REPEAT('..', ((LENGTH(ounder.hierarchy) - LENGTH(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officeName, c.firstname AS firstName, c.middlename AS middleName, c.lastname AS lastName, c.display_name AS fullName, c.mobile_no AS mobileNo, o.id AS officeNumber, DATE_PART('MONTH', AGE(CURRENT_DATE, c.activation_date)) AS dormant FROM m_office o JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarch [...]
+            <column name="description" value="All individuals who have not yet received a loan but were also entered into the system more than 3 months"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="172"/>
+            <column name="report_name" value="Active group leaders"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstName, c.middlename AS middleName, c.lastname AS lastName, c.display_name AS fullName, c.mobile_no AS mobileNo, CONCAT(REPEAT('..', ((LENGTH(ounder.hierarchy) - LENGTH(REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officeName, o.id AS officeNumber FROM m_office o JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarchy, '%') JOIN m_group g ON g.office_id = ounder.id JOIN m_client c ON  [...]
+            <column name="description" value="All active group chairmen"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="173"/>
+            <column name="report_name" value="Loan payments due (Overdue Loans)"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT mc.id AS id, mc.firstname AS firstName, mc.middlename AS middleName, mc.lastname AS lastName, mc.display_name AS fullName, mc.mobile_no AS mobileNo, ml.principal_amount AS loanAmount, (COALESCE(ml.principal_outstanding_derived, 0) + COALESCE(ml.interest_outstanding_derived, 0) + COALESCE(ml.fee_charges_outstanding_derived, 0) + COALESCE(ml.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, ml.principal_disbursed_derived AS loa [...]
+            <column name="description" value="Loan Payments Due between fromX to toY days for clients in arrears between overdueX and overdueY days"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="174"/>
+            <column name="report_name" value="Loan payments received (Active Loans)"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT mc.id AS id, mc.firstname AS firstName, mc.middlename AS middleName, mc.lastname AS lastName, mc.display_name AS fullName, mc.mobile_no AS mobileNo, ml.principal_amount AS loanAmount, (COALESCE(ml.principal_outstanding_derived, 0) + COALESCE(ml.interest_outstanding_derived, 0) + COALESCE(ml.fee_charges_outstanding_derived, 0) + COALESCE(ml.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, ounder.id AS officeNumber, ml.account [...]
+            <column name="description" value="Payments received in the last fromX to toY days for any loan with the status Active (on-time)"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="175"/>
+            <column name="report_name" value="Loan payments received (Overdue Loans)"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT ml.id AS loanId, mc.id AS id, mc.firstname AS firstName, mc.middlename AS middleName, mc.lastname AS lastName, mc.display_name AS fullName, mc.mobile_no AS mobileNo, ml.principal_amount AS loanAmount, (COALESCE(ml.principal_outstanding_derived, 0) + COALESCE(ml.interest_outstanding_derived, 0) + COALESCE(ml.fee_charges_outstanding_derived, 0) + COALESCE(ml.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, ounder.id AS officeN [...]
+            <column name="description" value="Payments received in the last fromX to toY days for any loan with the status Overdue (arrears) between overdueX and overdueY days"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="176"/>
+            <column name="report_name" value="Happy Birthday"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstName, c.middlename AS middleName,  c.lastname AS lastName, c.display_name AS fullName,  c.mobile_no AS mobileNo, CONCAT(REPEAT('..', ((LENGTH(ounder.hierarchy) - LENGTH( REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officeName,   o.id AS officeNumber, c.date_of_birth AS dateOfBirth,  CASE WHEN c.date_of_birth IS NULL THEN 0 ELSE CEIL(EXTRACT(DAY FROM (CURRENT_DATE - c.date_of_birth))/365) EN [...]
+            <column name="description" value="This sends a message to all clients with the status Active on their Birthday"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="177"/>
+            <column name="report_name" value="Loan fully repaid"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstName, c.middlename AS middleName, c.lastname AS lastName, c.display_name AS fullName, c.mobile_no AS mobileNo, l.principal_amount AS loanAmount, (COALESCE(l.principal_outstanding_derived, 0) + COALESCE(l.interest_outstanding_derived, 0) + COALESCE(l.fee_charges_outstanding_derived, 0) + COALESCE(l.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, l.principal_disbursed_derived AS loanDisbursed,  [...]
+            <column name="description" value="All loans that have been fully repaid (Closed or Overpaid) in the last fromX to toY days"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="178"/>
+            <column name="report_name" value="Loan outstanding after final instalment date"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="NonTriggered"/>
+            <column name="report_category" value="Loan"/>
+            <column name="report_sql" value="SELECT c.id AS id, c.firstname AS firstName, c.middlename AS middleName, c.lastname AS lastName, c.display_name AS fullName, c.mobile_no AS mobileNo, l.principal_amount AS loanAmount, o.id AS officeNumber, (COALESCE(l.principal_outstanding_derived, 0) + COALESCE(l.interest_outstanding_derived, 0) + COALESCE(l.fee_charges_outstanding_derived, 0) + COALESCE(l.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, l.principal_disbursed_deri [...]
+            <column name="description" value="All active loans (with an outstanding balance) between fromX to toY days after the final instalment date on their loan schedule"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="179"/>
+            <column name="report_name" value="Loan Repayment"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="select ml.id as loanId, mc.id, mc.firstname, COALESCE(mc.middlename, '') as middlename, mc.lastname, mc.display_name as FullName, mobile_no as mobileNo, mc.group_name as GroupName, round(ml.principal_amount, ml.currency_digits) as LoanAmount, round(ml.&quot;total_outstanding_derived&quot;, ml.currency_digits) as LoanOutstanding, ml.&quot;account_no&quot; as LoanAccountId, round(mlt.amountPaid, ml.currency_digits) as repaymentAmount FROM m_offi [...]
+            <column name="description" value="Loan Repayment"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="180"/>
+            <column name="report_name" value="Loan Approved"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT mc.id, mc.firstname, mc.middlename as middlename, mc.lastname, mc.display_name as FullName, mc.mobile_no as mobileNo, mc.group_name as GroupName, mo.name as officename, ml.id as loanId, ml.account_no as accountnumber, ml.principal_amount_proposed as loanamount, ml.annual_nominal_interest_rate as annualinterestrate FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, '%') AND ounder.hierarchy like CONCAT('. [...]
+            <column name="description" value="Loan and client data of approved loan"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="181"/>
+            <column name="report_name" value="Loan Rejected"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT mc.id, mc.firstname, mc.middlename as middlename, mc.lastname, mc.display_name as FullName, mc.mobile_no as mobileNo, mc.group_name as GroupName,  mo.name as officename, ml.id as loanId, ml.account_no as accountnumber, ml.principal_amount_proposed as loanamount, ml.annual_nominal_interest_rate as annualinterestrate  FROM m_office mo  JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, '%')  AND ounder.hierarchy like CONCA [...]
+            <column name="description" value="Loan and client data of rejected loan"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="falsee"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="182"/>
+            <column name="report_name" value="Client Rejected"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id,   c.firstname AS firstName,  c.middlename AS middleName,  c.lastname AS lastName,  c.display_name AS fullName,  c.mobile_no AS mobileNo, CONCAT(REPEAT('..', ((LENGTH(ounder.hierarchy) - LENGTH( REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officeName,   o.id AS officeNumber  FROM m_office o  JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarchy, '%')  JOIN m_client c ON c.office_id = ounder.id  LEFT  [...]
+            <column name="description" value="Client Rejection"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="183"/>
+            <column name="report_name" value="Client Activated"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category" value="Client"/>
+            <column name="report_sql" value="SELECT c.id AS id,   c.firstname AS firstName,  c.middlename AS middleName,  c.lastname AS lastName,  c.display_name AS fullName,  c.mobile_no AS mobileNo, CONCAT(REPEAT('..', ((LENGTH(ounder.hierarchy) - LENGTH( REPLACE(ounder.hierarchy, '.', '')) - 1))), ounder.name) AS officeName,   o.id AS officeNumber  FROM m_office o  JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarchy, '%')  JOIN m_client c ON c.office_id = ounder.id  LEFT  [...]
+            <column name="description" value="Client Activation"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="184"/>
+            <column name="report_name" value="Savings Rejected"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category" value="Savings"/>
+            <column name="report_sql" value="SELECT   c.id AS id,  c.firstname AS firstName, c.middlename AS middleName,  c.lastname AS lastName, c.display_name AS fullName,  c.mobile_no AS mobileNo, s.account_no AS savingsAccountNo,  ounder.id AS officeNumber,  ounder.name AS officeName    FROM m_office o JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarchy, '%')  JOIN m_client c ON c.office_id = ounder.id  JOIN m_savings_account s ON s.client_id = c.id JOIN m_savings_produc [...]
+            <column name="description" value="Savings Rejected"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="185"/>
+            <column name="report_name" value="Savings Activated"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category" value="Savings"/>
+            <column name="report_sql" value="SELECT   c.id AS id,  c.firstname AS firstName, c.middlename AS middleName,  c.lastname AS lastName, c.display_name AS fullName,  c.mobile_no AS mobileNo, s.account_no AS savingsAccountNo,  ounder.id AS officeNumber,  ounder.name AS officeName    FROM m_office o JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(o.hierarchy, '%')  JOIN m_client c ON c.office_id = ounder.id  JOIN m_savings_account s ON s.client_id = c.id JOIN m_savings_produc [...]
+            <column name="description" value="Savings Activation"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="186"/>
+            <column name="report_name" value="Savings Deposit"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT sc.savingsId AS savingsId, sc.id AS clientId, sc.firstname, COALESCE(sc.middlename,'') AS middlename, sc.lastname, sc.display_name AS FullName, sc.mobile_no AS mobileNo, ms.&quot;account_no&quot; AS savingsAccountNo, ROUND(mst.amountPaid, ms.currency_digits) AS depositAmount, ms.account_balance_derived AS balance, mst.transactionDate AS transactionDate FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, ' [...]
+            <column name="description" value="Savings Deposit"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="187"/>
+            <column name="report_name" value="Savings Withdrawal"/>
+            <column name="report_type" value="SMS"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="SELECT sc.savingsId AS savingsId, sc.id AS clientId, sc.firstname, COALESCE(sc.middlename,'') AS middlename, sc.lastname, sc.display_name AS FullName, sc.mobile_no AS mobileNo,  ms.&quot;account_no&quot; AS savingsAccountNo, ROUND(mst.amountPaid, ms.currency_digits) AS withdrawAmount, ms.account_balance_derived AS balance, mst.transactionDate AS transactionDate FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, [...]
+            <column name="description" value="Savings Withdrawal"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="188"/>
+            <column name="report_name" value="ReportCategoryList"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="(NULL)"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="189"/>
+            <column name="report_name" value="FullReportList"/>
+            <column name="report_type" value="Table"/>
+            <column name="report_subtype"/>
+            <column name="report_category" value="(NULL)"/>
+            <column name="report_sql" value="(NULL)"/>
+            <column name="description" value="(NULL)"/>
+            <column name="core_report" valueBoolean="true"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="190"/>
+            <column name="report_name" value="Loan Approved - Email"/>
+            <column name="report_type" value="Email"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="select  ml.id as loanId,  COALESCE(mc.id,mc2.id) as id,  COALESCE(mc.firstname,mc2.firstname) as firstname,  \nCOALESCE(mc.middlename,mc2.middlename,(\'\')) as middlename, COALESCE(mc.lastname,mc2.lastname) as lastname,  \nCOALESCE(mc.display_name,mc2.display_name) as display_name, COALESCE(mc.status_enum,mc2.status_enum) as status_enum, \nCOALESCE(mc.mobile_no,mc2.mobile_no) as mobile_no, COALESCE(mg.office_id,mc2.office_id) as office_id, COA [...]
+            <column name="description" value="Loan and client data of approved loan"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="191"/>
+            <column name="report_name" value="Loan Rejected - Email"/>
+            <column name="report_type" value="Email"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="select  ml.id as loanId,  COALESCE(mc.id,mc2.id) as id,  COALESCE(mc.firstname,mc2.firstname) as firstname,  \nCOALESCE(mc.middlename,mc2.middlename,(\'\')) as middlename, COALESCE(mc.lastname,mc2.lastname) as lastname,  \nCOALESCE(mc.display_name,mc2.display_name) as display_name, COALESCE(mc.status_enum,mc2.status_enum) as status_enum, \nCOALESCE(mc.mobile_no,mc2.mobile_no) as mobile_no, COALESCE(mg.office_id,mc2.office_id) as office_id, COA [...]
+            <column name="description" value="Loan and client data of rejected loan"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+        <insert tableName="stretchy_report">
+            <column name="id" valueNumeric="192"/>
+            <column name="report_name" value="Loan Repayment - Email"/>
+            <column name="report_type" value="Email"/>
+            <column name="report_subtype" value="Triggered"/>
+            <column name="report_category"/>
+            <column name="report_sql" value="select  ml.id as loanId,  COALESCE(mc.id,mc2.id) as id,  COALESCE(mc.firstname,mc2.firstname) as firstname,  \nCOALESCE(mc.middlename,mc2.middlename,(\'\')) as middlename, COALESCE(mc.lastname,mc2.lastname) as lastname,  \nCOALESCE(mc.display_name,mc2.display_name) as display_name,  COALESCE(mc.status_enum,mc2.status_enum) as status_enum, \n COALESCE(mc.mobile_no,mc2.mobile_no) as mobile_no, COALESCE(mg.office_id,mc2.office_id) as office_id, C [...]
+            <column name="description" value="Loan and client data of loan repayment"/>
+            <column name="core_report" valueBoolean="false"/>
+            <column name="use_report" valueBoolean="true"/>
+            <column name="self_service_user_report" valueBoolean="false"/>
+        </insert>
+    </changeSet>
+    <changeSet author="fineract" id="3-postgresql" context="postgresql">
+        <sql>
+            SELECT SETVAL('c_cache_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM c_cache;
+            SELECT SETVAL('c_configuration_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM c_configuration;
+            SELECT SETVAL('c_external_service_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM c_external_service;
+            SELECT SETVAL('job_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM job;
+            SELECT SETVAL('job_parameters_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM job_parameters;
+            SELECT SETVAL('m_appuser_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_appuser;
+            SELECT SETVAL('m_code_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_code;
+            SELECT SETVAL('m_code_value_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_code_value;
+            SELECT SETVAL('m_creditbureau_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_creditbureau;
+            SELECT SETVAL('m_creditbureau_configuration_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_creditbureau_configuration;
+            SELECT SETVAL('m_currency_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_currency;
+            SELECT SETVAL('m_entity_relation_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_entity_relation;
+            SELECT SETVAL('m_field_configuration_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_field_configuration;
+            SELECT SETVAL('m_group_level_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_group_level;
+            SELECT SETVAL('m_hook_schema_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_hook_schema;
+            SELECT SETVAL('m_hook_templates_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_hook_templates;
+            SELECT SETVAL('m_office_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_office;
+            SELECT SETVAL('m_organisation_currency_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_organisation_currency;
+            SELECT SETVAL('m_password_validation_policy_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_password_validation_policy;
+            SELECT SETVAL('m_payment_type_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_payment_type;
+            SELECT SETVAL('m_permission_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_permission;
+            SELECT SETVAL('m_provision_category_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_provision_category;
+            SELECT SETVAL('m_report_mailing_job_configuration_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_report_mailing_job_configuration;
+            SELECT SETVAL('m_role_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_role;
+            SELECT SETVAL('m_working_days_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM m_working_days;
+            SELECT SETVAL('mix_taxonomy_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM mix_taxonomy;
+            SELECT SETVAL('mix_taxonomy_mapping_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM mix_taxonomy_mapping;
+            SELECT SETVAL('mix_xbrl_namespace_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM mix_xbrl_namespace;
+            SELECT SETVAL('ppi_scores_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM ppi_scores;
+            SELECT SETVAL('ref_loan_transaction_processing_strategy_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM ref_loan_transaction_processing_strategy;
+            SELECT SETVAL('scheduled_email_configuration_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM scheduled_email_configuration;
+            SELECT SETVAL('scheduler_detail_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM scheduler_detail;
+            SELECT SETVAL('topic_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM topic;
+            SELECT SETVAL('topic_subscriber_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM topic_subscriber;
+            SELECT SETVAL('stretchy_parameter_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM stretchy_parameter;
+            SELECT SETVAL('stretchy_report_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM stretchy_report;
+            SELECT SETVAL('stretchy_report_parameter_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM stretchy_report_parameter;
+            SELECT SETVAL('twofactor_configuration_id_seq', COALESCE(MAX(id), 0)+1, false ) FROM twofactor_configuration;
+        </sql>
+    </changeSet>
+    <changeSet author="fineract" id="883-postgresql" context="postgresql">
+        <addForeignKeyConstraint baseColumnNames="report_id" baseTableName="stretchy_report_parameter"
+                                 constraintName="fk_report_parameter_001" deferrable="false" initiallyDeferred="false"
+                                 onDelete="CASCADE" onUpdate="NO ACTION" referencedColumnNames="id"
+                                 referencedTableName="stretchy_report" validate="true"/>
+    </changeSet>
+    <changeSet author="fineract" id="884-postgresql" context="postgresql">
+        <addForeignKeyConstraint baseColumnNames="parameter_id" baseTableName="stretchy_report_parameter"
+                                 constraintName="fk_report_parameter_002" deferrable="false" initiallyDeferred="false"
+                                 onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id"
+                                 referencedTableName="stretchy_parameter" validate="true"/>
+    </changeSet>
+</databaseChangeLog>
diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0004_camelcase_column_renaming.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0004_camelcase_column_renaming.xml
new file mode 100644
index 0000000..f67cfa0
--- /dev/null
+++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0004_camelcase_column_renaming.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements. See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership. The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License. You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied. See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
+    <changeSet author="fineract" id="1" objectQuotingStrategy="QUOTE_ALL_OBJECTS">
+        <renameColumn tableName="m_adhoc" oldColumnName="IsActive" newColumnName="is_active" columnDataType="BOOLEAN"/>
+        <renameColumn tableName="m_creditbureau" oldColumnName="implementationKey" newColumnName="implementation_key" columnDataType="VARCHAR(100)"/>
+        <renameColumn tableName="m_creditbureau_loanproduct_mapping" oldColumnName="isActive" newColumnName="is_active" columnDataType="BOOLEAN"/>
+        <renameColumn tableName="m_creditbureau_token" oldColumnName="tokenType" newColumnName="token_type" columnDataType="VARCHAR(128)"/>
+        <renameColumn tableName="m_creditbureau_token" oldColumnName="expiresIn" newColumnName="expires_in" columnDataType="VARCHAR(128)"/>
+        <renameColumn tableName="m_creditbureau_token" oldColumnName="expiryDate" newColumnName="expiry_date" columnDataType="DATE"/>
+        <renameColumn tableName="m_creditreport" oldColumnName="creditBureauId" newColumnName="credit_bureau_id" columnDataType="BIGINT"/>
+        <renameColumn tableName="m_creditreport" oldColumnName="nationalId" newColumnName="national_id" columnDataType="VARCHAR(128)"/>
+        <renameColumn tableName="m_creditreport" oldColumnName="creditReports" newColumnName="credit_reports" columnDataType="BLOB"/>
+        <renameColumn tableName="m_organisation_creditbureau" oldColumnName="isActive" newColumnName="is_active" columnDataType="BOOLEAN"/>
+        <renameColumn tableName="scheduled_email_campaign" oldColumnName="businessRule_id" newColumnName="business_rule_id" columnDataType="INT"/>
+    </changeSet>
+</databaseChangeLog>
diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
index de35c63..d1c7ae8 100644
--- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
+++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/configuration/spring/TestsWithoutDatabaseAndNoJobsConfiguration.java
@@ -19,7 +19,9 @@
 package org.apache.fineract.infrastructure.configuration.spring;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
+import com.zaxxer.hikari.HikariConfig;
 import javax.sql.DataSource;
 import org.apache.fineract.infrastructure.core.boot.AbstractApplicationConfiguration;
 import org.apache.fineract.infrastructure.core.config.FineractProperties;
@@ -43,6 +45,13 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 public class TestsWithoutDatabaseAndNoJobsConfiguration extends AbstractApplicationConfiguration {
 
     @Bean
+    public HikariConfig hikariConfig() {
+        HikariConfig mock = mock(HikariConfig.class);
+        when(mock.getDriverClassName()).thenReturn("org.mariadb.jdbc.Driver");
+        return mock;
+    }
+
+    @Bean
     public TenantDataSourceFactory tenantDataSourceFactory() {
         return new TenantDataSourceFactory(null) {