You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by zt...@apache.org on 2021/11/01 03:35:45 UTC

[hawq] branch master updated: HAWQ-1811. Sync with OushuDB - Phase I

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

ztao1987 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hawq.git


The following commit(s) were added to refs/heads/master by this push:
     new e3181da  HAWQ-1811. Sync with OushuDB - Phase I
e3181da is described below

commit e3181dade779c7469d2e6a53ca622bb369b46fc8
Author: ztao1987 <zh...@gmail.com>
AuthorDate: Sat Oct 30 16:56:06 2021 +0800

    HAWQ-1811. Sync with OushuDB - Phase I
---
 GNUmakefile.in                                     |    5 +-
 .../orc_debug_metadata.py => hornet/Makefile}      |   25 +-
 contrib/hornet/hornet.c                            |  133 ++
 .../load_hornet_helper_function.sql}               |  195 ++-
 contrib/{oushu => hornet}/orc_debug_metadata.py    |    0
 contrib/{oushu => hornet}/orc_debug_statistics.py  |    0
 contrib/magma/magma.c                              |   34 +-
 contrib/magma/magma_install.sql                    |  223 ++-
 contrib/magma/monitor_install.sql                  |    6 -
 contrib/orc/orc_install.sql                        |   79 +-
 doc/src/sgml/ref/alter_table.sgml                  |    5 +-
 doc/src/sgml/ref/create_table.sgml                 |   10 +-
 doc/src/sgml/ref/create_table_as.sgml              |    5 +-
 src/backend/access/bitmap/bitmapattutil.c          |    1 +
 src/backend/access/external/url_curl.c             |   22 +-
 src/backend/access/nbtree/nbtsort.c                |    2 +-
 src/backend/access/nbtree/nbtutils.c               |    4 +-
 src/backend/access/orc/orcam.c                     |  143 +-
 src/backend/bootstrap/bootparse.y                  |   32 +-
 src/backend/catalog/Makefile                       |    5 +-
 src/backend/catalog/aoseg.c                        |    1 +
 src/backend/catalog/heap.c                         |    1 +
 src/backend/catalog/index.c                        |   24 +-
 src/backend/catalog/indexing.c                     |    1 +
 src/backend/catalog/pg_constraint.c                |   13 +-
 src/backend/catalog/toasting.c                     |    1 +
 src/backend/cdb/cdbmutate.c                        |    2 +-
 src/backend/cdb/cdbpartition.c                     |    2 +
 src/backend/commands/indexcmds.c                   |   33 +-
 src/backend/commands/tablecmds.c                   |    2 +
 src/backend/commands/typecmds.c                    |    1 +
 src/backend/executor/newExecutor.c                 |    7 +
 src/backend/nodes/copyfuncs.c                      |    2 +
 src/backend/nodes/equalfuncs.c                     |    2 +
 src/backend/nodes/outfast.c                        |    1 +
 src/backend/nodes/outfuncs.c                       |    4 +
 src/backend/optimizer/path/indxpath.c              |    4 +-
 src/backend/optimizer/plan/newPlanner.c            | 1764 +++++++++++---------
 src/backend/optimizer/plan/planagg.c               |    2 +-
 src/backend/optimizer/util/plancat.c               |   12 +-
 src/backend/parser/gram.y                          |   50 +-
 src/backend/parser/parse_utilcmd.c                 |  102 +-
 src/backend/utils/Gen_hawq_funcoid_mapping.sh      |   10 +-
 src/backend/utils/adt/array_distance_install.sql   |   17 +-
 src/backend/utils/adt/ruleutils.c                  |    8 +-
 src/backend/utils/adt/selfuncs.c                   |    2 +-
 src/backend/utils/cache/relcache.c                 |   19 +-
 src/backend/utils/misc/guc.c                       |    2 +-
 src/backend/utils/sort/tuplesort.c                 |    2 +-
 src/backend/utils/sort/tuplesort_mk.c              |    2 +-
 src/bin/pg_dump/pg_dump.c                          |   29 +-
 src/bin/pg_dump/pg_dump.h                          |    6 +-
 src/include/access/orcam.h                         |   60 +-
 src/include/catalog/index.h                        |   10 +-
 src/include/catalog/pg_attribute.h                 |   17 +-
 src/include/catalog/pg_constraint.h                |    1 +
 src/include/catalog/pg_index.h                     |   20 +-
 src/include/nodes/parsenodes.h                     |    6 +-
 src/include/nodes/relation.h                       |    4 +-
 src/include/optimizer/newPlanner.h                 |   12 +-
 src/include/parser/kwlist.h                        |    1 +
 src/include/utils/guc.h                            |    2 +
 src/include/utils/rel.h                            |   14 +
 tools/bin/upgrade.sh                               |   55 +-
 64 files changed, 2012 insertions(+), 1247 deletions(-)

diff --git a/GNUmakefile.in b/GNUmakefile.in
index 63d024b..df6da44 100644
--- a/GNUmakefile.in
+++ b/GNUmakefile.in
@@ -18,7 +18,7 @@ all:
 	$(MAKE) -C ranger-plugin $@
 	@echo "All of HAWQ successfully made. Ready to install."
 
-install:
+install: git-hook
 #	$(MAKE) -C doc $@
 #	$(MAKE) -C depends/libhdfs3 $@
 	$(MAKE) -C src $@
@@ -211,5 +211,8 @@ install-orca:
 	$(MAKE) -C depends/thirdparty/gp-xerces/build/ install
 	$(MAKE) -C depends/thirdparty/gporca/build/ install
 
+git-hook:
+	command -v git && git config --local core.hooksPath .github/ || true
+
 .PHONY: dist distdir distcheck
 #unexport split-dist
diff --git a/contrib/oushu/orc_debug_metadata.py b/contrib/hornet/Makefile
old mode 100755
new mode 100644
similarity index 67%
copy from contrib/oushu/orc_debug_metadata.py
copy to contrib/hornet/Makefile
index 8e1ab3b..e796651
--- a/contrib/oushu/orc_debug_metadata.py
+++ b/contrib/hornet/Makefile
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # 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
@@ -17,11 +16,19 @@
 # under the License.
 #
 
-import subprocess
-import sys
-import os
-p = os.popen('orc-metadata --verbose ' + sys.argv[2]).read().split("\n")
-f = ''
-for cas in p:
-    f += cas.replace('\n','')
-print(sys.argv[1] + '|' + f)
+MODULE_big = hornet
+OBJS      += hornet.o
+
+SCRIPTS = orc_debug_metadata.py orc_debug_statistics.py
+DATA = load_hornet_helper_function.sql
+
+ifdef USE_PGXS
+PGXS := $(shell pg_config --pgxs)
+include $(PGXS)
+else
+subdir = contrib/hornet
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+override SHLIB_LINK += -lhdfs3
+endif
diff --git a/contrib/hornet/hornet.c b/contrib/hornet/hornet.c
new file mode 100644
index 0000000..f149904
--- /dev/null
+++ b/contrib/hornet/hornet.c
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+#include "postgres.h"
+
+#include "funcapi.h"
+
+#include "hdfs/hdfs.h"
+#include "storage/fd.h"
+#include "storage/filesystem.h"
+#include "utils/builtins.h"
+
+Datum ls_hdfs_dir(PG_FUNCTION_ARGS);
+
+PG_MODULE_MAGIC;
+PG_FUNCTION_INFO_V1(ls_hdfs_dir);
+
+struct LsHdfsDirInfo {
+  hdfsFS fs;
+  hdfsFileInfo *fileInfos;
+  char hdfsPrefix[HOSTNAME_MAX_LENGTH];
+};
+
+#define NUM_LS_HDFS_DIR 5
+Datum ls_hdfs_dir(PG_FUNCTION_ARGS) {
+  FuncCallContext *funcctx;
+
+  if (SRF_IS_FIRSTCALL()) {
+    funcctx = SRF_FIRSTCALL_INIT();
+    TupleDesc tupdesc =
+        CreateTemplateTupleDesc(NUM_LS_HDFS_DIR, false /* hasoid */);
+    TupleDescInitEntry(tupdesc, (AttrNumber)1, "file_replication", INT4OID, -1,
+                       0);
+    TupleDescInitEntry(tupdesc, (AttrNumber)2, "file_owner", TEXTOID, -1, 0);
+    TupleDescInitEntry(tupdesc, (AttrNumber)3, "file_group", TEXTOID, -1, 0);
+    TupleDescInitEntry(tupdesc, (AttrNumber)4, "file_size", INT8OID, -1, 0);
+    TupleDescInitEntry(tupdesc, (AttrNumber)5, "file_name", TEXTOID, -1, 0);
+
+    funcctx->tuple_desc = BlessTupleDesc(tupdesc);
+
+    MemoryContext oldcontext =
+        MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+    const char *url = DatumGetCString(
+        DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
+    char *host = NULL, *protocol = NULL;
+    int port;
+
+    if (HdfsParsePath(url, &protocol, &host, &port, NULL) != 0) {
+      ereport(ERROR,
+              (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+               errmsg("invalid HDFS URL: \"%s\"", url), errOmitLocation(true)));
+      funcctx = SRF_PERCALL_SETUP();
+      SRF_RETURN_DONE(funcctx);
+    }
+    struct LsHdfsDirInfo *info = palloc0(sizeof(struct LsHdfsDirInfo));
+    const char *path = strstr(strstr(url, "://") + 3, "/");
+    strncpy(info->hdfsPrefix, url, path - url);
+
+    struct hdfsBuilder *builder = hdfsNewBuilder();
+    hdfsBuilderSetNameNode(builder, host);
+    if (port != 0)
+      hdfsBuilderSetNameNodePort(builder, port);
+    info->fs = hdfsBuilderConnect(builder);
+    hdfsFreeBuilder(builder);
+
+    if (info->fs == NULL) {
+      ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+                      errmsg("fail to connect HDFS URL: \"%s\"", url),
+                      errOmitLocation(true)));
+      funcctx = SRF_PERCALL_SETUP();
+      SRF_RETURN_DONE(funcctx);
+    }
+
+    info->fileInfos =
+        hdfsListDirectory(info->fs, path, (int *)&funcctx->max_calls);
+    funcctx->user_fctx = info;
+
+    MemoryContextSwitchTo(oldcontext);
+  }
+
+  funcctx = SRF_PERCALL_SETUP();
+  struct LsHdfsDirInfo *info = funcctx->user_fctx;
+
+  if (funcctx->call_cntr < funcctx->max_calls) {
+    Datum values[NUM_LS_HDFS_DIR];
+    bool nulls[NUM_LS_HDFS_DIR];
+    MemSet(nulls, 0, sizeof(nulls));
+
+    char *fileName =
+        palloc(strlen(info->hdfsPrefix) +
+               strlen(info->fileInfos[funcctx->call_cntr].mName) + 1);
+    fileName[0] = '\0';
+    strcat(fileName, info->hdfsPrefix);
+    strcat(fileName, info->fileInfos[funcctx->call_cntr].mName);
+    values[0] =
+        UInt64GetDatum(info->fileInfos[funcctx->call_cntr].mReplication);
+    values[1] = PointerGetDatum(
+        cstring_to_text(info->fileInfos[funcctx->call_cntr].mOwner));
+    values[2] = PointerGetDatum(
+        cstring_to_text(info->fileInfos[funcctx->call_cntr].mGroup));
+    values[3] = UInt64GetDatum(info->fileInfos[funcctx->call_cntr].mSize);
+    values[4] = PointerGetDatum(cstring_to_text(fileName));
+
+    HeapTuple tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
+    Datum result = HeapTupleGetDatum(tuple);
+
+    pfree(fileName);
+
+    SRF_RETURN_NEXT(funcctx, result);
+  } else {
+    hdfsFreeFileInfo(info->fileInfos, funcctx->max_calls);
+    hdfsDisconnect(info->fs);
+    pfree(info);
+    SRF_RETURN_DONE(funcctx);
+  }
+}
diff --git a/contrib/oushu/load_orc_debug_udf.sql b/contrib/hornet/load_hornet_helper_function.sql
similarity index 52%
rename from contrib/oushu/load_orc_debug_udf.sql
rename to contrib/hornet/load_hornet_helper_function.sql
index 0667263..5a157d5 100644
--- a/contrib/oushu/load_orc_debug_udf.sql
+++ b/contrib/hornet/load_hornet_helper_function.sql
@@ -1,46 +1,63 @@
---
--- debug_orc creates views to debug ORC table, leveraging the Apache ORC's tools.
---
--- The relation to debug provides its name as suffix, and the debug_orc action serves as prefix.
--- i.e.
--- Name the debug view in the form of debug_orc_{metadata,contents,statistics}_view_`relname`.
--- Name the intermediate table in the form of debug_orc_{metadata,contents,statistics}_table_`relname`.
---
--- debug_orc_metadata_table_`relname` dump the relation's content as a table.
+DROP SCHEMA IF EXISTS hornet_helper CASCADE;
+CREATE SCHEMA hornet_helper;
+SET SEARCH_PATH = hornet_helper;
 
-drop function if exists pg_aoseg(oid);
-create or replace function pg_aoseg(t oid)
-    returns table
+DROP FUNCTION IF EXISTS ls_hdfs_dir(TEXT);
+CREATE FUNCTION ls_hdfs_dir(location TEXT)
+    RETURNS table
             (
-                relname          text,
-                orientation      text,
-                segno            int,
-                tupcount         double precision,
-                eof              double precision,
-                eof_uncompressed double precision
+                file_replication int,
+                file_owner text,
+                file_group text,
+                file_size bigint,
+                file_name text
             )
+AS '$libdir/hornet', 'ls_hdfs_dir'
+LANGUAGE C IMMUTABLE;
+
+drop type if exists pg_aoseg;
+create type pg_aoseg as (relname          text,
+    orientation      text,
+    segno            int,
+    tupcount         double precision,
+    eof              double precision,
+    eof_uncompressed double precision
+    );
+
+drop function if exists pg_aoseg(VARIADIC oid[]);
+create or replace function pg_aoseg(VARIADIC reloids oid[])
+    returns setof pg_aoseg
 as
 $$
 declare
-    reloptions text[];
+    ret         hornet_helper.pg_aoseg;
+    reloid      oid;
+    relname     text;
+    reloptions  text[];
+    orientation text;
 begin
-    select pg_class.relname from pg_class where oid = t into relname;
-    select pg_class.reloptions from pg_class where oid = t into reloptions;
-    select case
-               when
-                   'orientation=parquet' = any (reloptions) then 'paq'
-               when
-                   'orientation=orc' = any (reloptions) then 'orc'
-               else 'ao'
-               end
-    into orientation;
-
-    for segno, tupcount, eof, eof_uncompressed in EXECUTE
-                        'SELECT segno, tupcount, eof, eofuncompressed from pg_aoseg.pg_' || orientation || 'seg_' ||
-                        t::text ||
-                        ' ORDER BY segno'
+    for reloid in select reloids[idx] from (select generate_series(1, array_upper(reloids, 1))) f(idx)
         loop
-            return next;
+            select pg_class.relname from pg_class where oid = reloid into relname;
+            select pg_class.reloptions from pg_class where oid = reloid into reloptions;
+            select case
+                       when
+                           'orientation=parquet' = any (reloptions) then 'paq'
+                       when
+                           'orientation=orc' = any (reloptions) then 'orc'
+                       else 'ao'
+                       end
+            into orientation;
+
+            for ret in EXECUTE
+                                    'SELECT ''' || relname::text || ''',''' || orientation::text || ''',' ||
+                                    'segno, tupcount, eof, eofuncompressed from pg_aoseg.pg_' || orientation ||
+                                    'seg_' ||
+                                    reloid::text ||
+                                    ' ORDER BY segno'
+                loop
+                    return next ret;
+                end loop;
         end loop;
 end;
 $$ language plpgsql;
@@ -50,51 +67,56 @@ CREATE or replace FUNCTION ls_hdfs_table_location(reloid oid)
     RETURNS setof text
 AS
 $$
-plan = plpy.prepare("select location from pg_exttable where reloid = $1", ["oid"])
-rv = plpy.execute(plan, [reloid], 1)
-
-if len(rv) != 0:                 # external table
-    loc_list = rv[0]["location"]
-else:                            # internal orc table
-    plan = plpy.prepare("select 'hdfs://' || pg_settings.setting || '/' || pg_database.dat2tablespace || '/' || pg_database.oid || '/' || pg_class.relfilenode from pg_settings,pg_database,pg_class where pg_settings.name = 'hawq_dfs_url' and datname = current_database() and pg_class.oid = $1;", ["oid"])
-    rv= plpy.execute(plan, [reloid], 1)
-    loc_list = [rv[0]["?column?"]]
-
-return loc_list
-$$ LANGUAGE plpythonu;
+declare
+    locations text[];
+    location  text;
+begin
+    select pg_exttable.location
+    from pg_exttable
+    where pg_exttable.reloid = reloid
+    into locations;
+    if locations is not null then
+        for location in select locations[idx]
+                        from (select generate_series(1,
+                                                     array_upper(locations, 1))) f(idx)
+            loop
+                return next location;
+            end loop;
+    else
+        for location in select 'hdfs://' || pg_settings.setting || '/' ||
+                               pg_database.dat2tablespace || '/' ||
+                               pg_database.oid || '/' || pg_class.relfilenode
+                        from pg_settings,
+                             pg_database,
+                             pg_class
+                        where pg_settings.name = 'hawq_dfs_url'
+                          and datname = current_database()
+                          and pg_class.oid = reloid
+            loop
+                return next location;
+            end loop;
+    end if;
+end;
+$$ LANGUAGE plpgsql;
 
 drop function if exists ls_hdfs_table_file_list(oid);
 CREATE or replace FUNCTION ls_hdfs_table_file_list(reloid oid)
     RETURNS setof text
 AS
-$$
-import subprocess
-
-plan = plpy.prepare("select location from pg_exttable where reloid = $1", ["oid"])
-rv = plpy.execute(plan, [reloid], 1)
-if len(rv) != 0:   #ext orc table
-    loc_list = rv[0]["location"]
-
-    hdfs_ls = lambda loc: subprocess.Popen(['hdfs', 'dfs', '-ls', '-C', loc],
-                                        stdout=subprocess.PIPE).communicate()[0].split("\n")
-    result = sum(map(hdfs_ls, loc_list), [])
-    result = filter(lambda x: len(x) and 'tmp' not in x, result)
-    return result
-else:    # internal orc table
-    plan = plpy.prepare("select 'hdfs://' || pg_settings.setting || '/' || pg_database.dat2tablespace || '/' || pg_database.oid || '/' || pg_class.relfilenode from pg_settings,pg_database,pg_class where pg_settings.name = 'hawq_dfs_url' and datname = current_database() and pg_class.oid = $1;", ["oid"])
-    rv= plpy.execute(plan, [reloid], 1)
-    loc_list_tmp = rv[0]["?column?"]
-    loc_list = []
-    loc_list.append(loc_list_tmp)
-    hdfs_ls = lambda loc: subprocess.Popen(['hdfs', 'dfs', '-ls', '-C', loc],
-                                        stdout=subprocess.PIPE).communicate()[0].split("\n")
-    result = sum(map(hdfs_ls, loc_list), [])
-
-    result = filter(lambda x: len(x) and 'tmp' not in x, result)
-    return result;
-
-$$ LANGUAGE plpythonu;
+'select * from (select (hornet_helper.ls_hdfs_dir(ls_hdfs_table_location)).file_name
+ from hornet_helper.ls_hdfs_table_location($1)) t where file_name !~ ''.tmp$'';'
+    LANGUAGE SQL;
 
+
+--
+-- debug_orc creates views to debug ORC table, leveraging the Apache ORC's tools.
+--
+-- The relation to debug provides its name as suffix, and the debug_orc action serves as prefix.
+-- i.e.
+-- Name the debug view in the form of debug_orc_{metadata,contents,statistics}_view_`relname`.
+-- Name the intermediate table in the form of debug_orc_{metadata,contents,statistics}_table_`relname`.
+--
+-- debug_orc_metadata_table_`relname` dump the relation's content as a table.
 DROP FUNCTION IF EXISTS debug_orc(rel regclass);
 CREATE OR REPLACE FUNCTION debug_orc(rel regclass) RETURNS text AS
 $$
@@ -126,25 +148,14 @@ BEGIN
     -- Generate command to execute on segment, distributing job according to GP_SEGMENT_ID
     segIdx := 0;
     contents_command := '';
-    drop table if exists hdfs_file_path_table;
-    create temp table hdfs_file_path_table(path text);
-    insert into hdfs_file_path_table select * from ls_hdfs_table_file_list(rel::oid);
-    for url in select * from hdfs_file_path_table
+    meta_command :='';
+    st_command :='';
+    for url in select * from hornet_helper.ls_hdfs_table_file_list(rel::oid)
         loop
             segIdx := (segIdx + 1) % segCount;
             contents_command := contents_command || E'\n' || 'test $GP_SEGMENT_ID -ne ' ||
                        segIdx || ' || orc-contents ' || url || ';';
-        end loop;
-
-    meta_command :='';
-    for url in select * from hdfs_file_path_table
-        loop
             meta_command := meta_command || ' orc_debug_metadata.py ' ||relName|| ' '||url || ';';
-        end loop;
-
-    st_command :='';
-    for url in select * from hdfs_file_path_table
-        loop
             st_command := st_command || ' orc_debug_statistics.py ' ||relName|| ' '||url || ';';
         end loop;
 
@@ -163,16 +174,16 @@ BEGIN
             'master' || ' FORMAT ''TEXT'''||'(DELIMITER ''|'' escape ''off'')';
 
    EXECUTE '
-            CREATE VIEW debug_orc_metadata_view_' ||relName || 
+            CREATE VIEW debug_orc_metadata_view_' ||relName ||
             '  as select table_name,jsonb_pretty(metadata) as metadata from debug_orc_metadata_table_' ||relName ||';';
-   
+
    EXECUTE '
             CREATE READABLE EXTERNAL WEB TABLE debug_orc_statistics_table_' ||
             relName || '(table_name text, statistics jsonb) EXECUTE ''' || st_command || ''' ON ' ||
             'master' || ' FORMAT ''TEXT'''||'(DELIMITER ''|'' escape ''off'')';
-   
+
    EXECUTE '
-           CREATE VIEW  debug_orc_statistics_view_' || relName || 
+           CREATE VIEW  debug_orc_statistics_view_' || relName ||
            '  as select table_name,jsonb_pretty(statistics) as statistics from debug_orc_statistics_table_' ||relName ||';';
 
     return contents_command;
diff --git a/contrib/oushu/orc_debug_metadata.py b/contrib/hornet/orc_debug_metadata.py
similarity index 100%
rename from contrib/oushu/orc_debug_metadata.py
rename to contrib/hornet/orc_debug_metadata.py
diff --git a/contrib/oushu/orc_debug_statistics.py b/contrib/hornet/orc_debug_statistics.py
similarity index 100%
rename from contrib/oushu/orc_debug_statistics.py
rename to contrib/hornet/orc_debug_statistics.py
diff --git a/contrib/magma/magma.c b/contrib/magma/magma.c
index 436afa4..08bbf40 100644
--- a/contrib/magma/magma.c
+++ b/contrib/magma/magma.c
@@ -327,6 +327,7 @@ static inline List *SortMagmaFilesByRangeId(List *files, int32_t length) {
  * Get magma node status
  */
 Datum magma_getstatus(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   elog(DEBUG1, "magma_getstatus begin");
   ExtProtocolMagmaInfo magmadata =
       palloc0(sizeof(ExtProtocolMagmaStatusData));
@@ -351,6 +352,7 @@ Datum magma_getstatus(PG_FUNCTION_ARGS) {
  * Implementation of blocklocation for magma protocol in pluggable storage
  */
 Datum magma_protocol_blocklocation(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   elog(DEBUG3, "magma_protocol_blocklocation begin");
   /*
    * Step 1. prepare instances
@@ -473,6 +475,7 @@ Datum magma_protocol_blocklocation(PG_FUNCTION_ARGS) {
  * Implementation of tablesize caculation for magma protocol in pluggable storage
  */
 Datum magma_protocol_tablesize(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   elog(DEBUG3, "magma_protocol_tablesize begin");
   /*
    * Step 1. prepare instances
@@ -547,6 +550,7 @@ Datum magma_protocol_tablesize(PG_FUNCTION_ARGS) {
  */
 
 Datum magma_protocol_databasesize(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   elog(DEBUG3, "magma_protocol_databasesize begin");
   /*
    * Step 1. prepare instances
@@ -595,6 +599,7 @@ Datum magma_protocol_databasesize(PG_FUNCTION_ARGS) {
  */
 
 Datum magma_protocol_validate(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   elog(DEBUG3, "magma_protocol_validate begin");
 
   /* Check action to be performed */
@@ -638,6 +643,7 @@ Datum magma_protocol_validate(PG_FUNCTION_ARGS) {
  * magma_validate_interfaces(char *formatName)
  */
 Datum magma_validate_interfaces(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorageValidator psv_interface = (PlugStorageValidator)(fcinfo->context);
 
   if (pg_strncasecmp(psv_interface->format_name, "magma",
@@ -658,6 +664,7 @@ Datum magma_validate_interfaces(PG_FUNCTION_ARGS) {
  *                     bool isWritable)
  */
 Datum magma_validate_options(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorageValidator psv = (PlugStorageValidator)(fcinfo->context);
 
   List *format_opts = psv->format_opts;
@@ -743,6 +750,7 @@ Datum magma_validate_options(PG_FUNCTION_ARGS) {
  * magma_validate_encodings(char *encodingName)
  */
 Datum magma_validate_encodings(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorageValidator psv = (PlugStorageValidator)(fcinfo->context);
   char *encoding_name = psv->encoding_name;
 
@@ -764,6 +772,7 @@ Datum magma_validate_encodings(PG_FUNCTION_ARGS) {
  * magma_validate_datatypes(TupleDesc tupDesc)
  */
 Datum magma_validate_datatypes(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorageValidator psv = (PlugStorageValidator)(fcinfo->context);
   TupleDesc tup_desc = psv->tuple_desc;
 
@@ -807,6 +816,7 @@ Datum magma_validate_datatypes(PG_FUNCTION_ARGS) {
 }
 
 Datum magma_createindex(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   char *dbname = ps->ps_db_name;
   char *schemaname = ps->ps_schema_name;
@@ -815,9 +825,9 @@ Datum magma_createindex(PG_FUNCTION_ARGS) {
   MagmaSnapshot *snapshot = &(ps->ps_snapshot);
 
   elog(DEBUG1, "create index use index name:%s, index type:%s,"
-      " columns counts:%d, unique:%d, primary:%d",
+      " columns counts:%d, key counts:%d, unique:%d, primary:%d",
       magmaidx->indexName, magmaidx->indexType, magmaidx->colCount,
-      magmaidx->unique, magmaidx->primary);
+      magmaidx->keynums, magmaidx->unique, magmaidx->primary);
 
   /* create index in magma */
   MagmaClientC *client = create_magma_client_instance();
@@ -833,6 +843,7 @@ Datum magma_createindex(PG_FUNCTION_ARGS) {
 }
 
 Datum magma_dropindex(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   char *dbname = ps->ps_db_name;
   char *schemaname = ps->ps_schema_name;
@@ -856,6 +867,7 @@ Datum magma_dropindex(PG_FUNCTION_ARGS) {
 }
 
 Datum magma_reindex_index(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   char *dbname = ps->ps_db_name;
   char *schemaname = ps->ps_schema_name;
@@ -891,6 +903,7 @@ Datum magma_reindex_index(PG_FUNCTION_ARGS) {
  *                IndexStmt *primarykey)
  */
 Datum magma_createtable(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
 
   char *dbname = ps->ps_db_name;
@@ -1030,6 +1043,7 @@ Datum magma_createtable(PG_FUNCTION_ARGS) {
  *              char *tablename)
  */
 Datum magma_droptable(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
 
   // ExtTableEntry *ete = ps->ps_exttable;
@@ -1054,6 +1068,7 @@ Datum magma_droptable(PG_FUNCTION_ARGS) {
 }
 
 Datum magma_beginscan(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalScan *ext_scan = ps->ps_ext_scan;
   ScanState *scan_state = ps->ps_scan_state;
@@ -1335,6 +1350,7 @@ void free_common_plan_context(CommonPlanContext *ctx) {
  *                 ExternalScanState *extScanState)
  */
 Datum magma_getnext_init(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   // PlanState *plan_state = ps->ps_plan_state;
   // ExternalScanState *ext_scan_state = ps->ps_ext_scan_state;
@@ -1365,6 +1381,7 @@ Datum magma_getnext_init(PG_FUNCTION_ARGS) {
 }
 
 Datum magma_getnext(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   FileScanDesc fsd = ps->ps_file_scan_desc;
   GlobalFormatUserData *user_data =
@@ -1481,6 +1498,7 @@ Datum magma_getnext(PG_FUNCTION_ARGS) {
  * magma_rescan(FileScanDesc scan)
  */
 Datum magma_rescan(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   FileScanDesc fsd = ps->ps_file_scan_desc;
   MagmaSnapshot *snapshot = &(ps->ps_snapshot);
@@ -1565,6 +1583,7 @@ Datum magma_rescan(PG_FUNCTION_ARGS) {
  * magma_endscan(FileScanDesc scan)
  */
 Datum magma_endscan(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   FileScanDesc fsd = ps->ps_file_scan_desc;
 
@@ -1632,6 +1651,7 @@ Datum magma_endscan(PG_FUNCTION_ARGS) {
  * magma_stopscan(FileScanDesc scan)
  */
 Datum magma_stopscan(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   FileScanDesc fsd = ps->ps_file_scan_desc;
   GlobalFormatUserData *user_data =
@@ -1683,6 +1703,7 @@ Datum magma_stopscan(PG_FUNCTION_ARGS) {
  * magma_begindelete(Relation relation)
  */
 Datum magma_begindelete(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   Relation relation = ps->ps_relation;
   char *serializeSchema = ps->ps_magma_serializeSchema;
@@ -1901,6 +1922,7 @@ Datum magma_begindelete(PG_FUNCTION_ARGS) {
  *           TupleTableSlot *tupTableSlot)
  */
 Datum magma_delete(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalInsertDesc edd = ps->ps_ext_delete_desc;
   TupleTableSlot *tts = ps->ps_tuple_table_slot;
@@ -2071,6 +2093,7 @@ Datum magma_delete(PG_FUNCTION_ARGS) {
  * magma_enddelete(ExternalInsertDesc extDeleteDesc)
  */
 Datum magma_enddelete(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalInsertDesc edd = ps->ps_ext_delete_desc;
 
@@ -2121,6 +2144,7 @@ Datum magma_enddelete(PG_FUNCTION_ARGS) {
  * magma_beginupdate(Relation relation)
  */
 Datum magma_beginupdate(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   Relation relation = ps->ps_relation;
   char *serializeSchema = ps->ps_magma_serializeSchema;
@@ -2343,6 +2367,7 @@ Datum magma_beginupdate(PG_FUNCTION_ARGS) {
  *           TupleTableSlot *tupTableSlot)
  */
 Datum magma_update(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalInsertDesc eud = ps->ps_ext_update_desc;
   TupleTableSlot *tts = ps->ps_tuple_table_slot;
@@ -2522,6 +2547,7 @@ Datum magma_update(PG_FUNCTION_ARGS) {
  * magma_endupdate(ExternalInsertDesc extUpdDesc)
  */
 Datum magma_endupdate(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalInsertDesc eud = ps->ps_ext_update_desc;
 
@@ -2570,6 +2596,7 @@ Datum magma_endupdate(PG_FUNCTION_ARGS) {
  *                char *formatterName)
  */
 Datum magma_insert_init(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   Relation relation = ps->ps_relation;
   int formatterType = ps->ps_formatter_type;
@@ -2825,6 +2852,7 @@ Datum magma_insert_init(PG_FUNCTION_ARGS) {
  *           TupleTableSlot *tupTableSlot)
  */
 Datum magma_insert(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalInsertDesc eid = ps->ps_ext_insert_desc;
   TupleTableSlot *tts = ps->ps_tuple_table_slot;
@@ -3010,6 +3038,7 @@ Datum magma_insert(PG_FUNCTION_ARGS) {
  * magma_insert_finish(ExternalInsertDesc extInsertDesc)
  */
 Datum magma_insert_finish(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   ExternalInsertDesc eid = ps->ps_ext_insert_desc;
 
@@ -3058,6 +3087,7 @@ Datum magma_insert_finish(PG_FUNCTION_ARGS) {
  * magma_transaction(PlugStorageTransaction transaction)
  */
 Datum magma_transaction(PG_FUNCTION_ARGS) {
+  checkOushuDbExtensiveFunctionSupport(__func__);
   elog(DEBUG3, "magma_transaction begin");
   PlugStorage ps = (PlugStorage)(fcinfo->context);
   PlugStorageTransaction pst = ps->ps_transaction;
diff --git a/contrib/magma/magma_install.sql b/contrib/magma/magma_install.sql
index 6229261..fdac581 100644
--- a/contrib/magma/magma_install.sql
+++ b/contrib/magma/magma_install.sql
@@ -1,217 +1,332 @@
 ------------------------------------------------------------------
 -- magma protocol
 ------------------------------------------------------------------
-CREATE OR REPLACE FUNCTION pg_catalog.magma_validate() RETURNS void
+DROP FUNCTION IF EXISTS pg_catalog.magma_validate();
+DROP FUNCTION IF EXISTS pg_catalog.magma_blocklocation();
+DROP FUNCTION IF EXISTS pg_catalog.magma_tablesize();
+DROP FUNCTION IF EXISTS pg_catalog.magma_databasesize();
+DROP FUNCTION IF EXISTS pg_catalog.magma_getstatus();
+
+set gen_new_oid_value to 11000;
+CREATE FUNCTION pg_catalog.magma_validate() RETURNS void
 AS '$libdir/magma.so', 'magma_protocol_validate'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_blocklocation() RETURNS void
+set gen_new_oid_value to 11001;
+CREATE FUNCTION pg_catalog.magma_blocklocation() RETURNS void
 AS '$libdir/magma.so', 'magma_protocol_blocklocation'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_tablesize() RETURNS void
+set gen_new_oid_value to 11002;
+CREATE FUNCTION pg_catalog.magma_tablesize() RETURNS void
 AS '$libdir/magma.so', 'magma_protocol_tablesize'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_databasesize() RETURNS void
+set gen_new_oid_value to 11003;
+CREATE FUNCTION pg_catalog.magma_databasesize() RETURNS void
 AS '$libdir/magma.so', 'magma_protocol_databasesize'
 LANGUAGE C STABLE;
 
+-- this function is builtin function which can not be dropped, replace if exsits
+set gen_new_oid_value to 5085;
+CREATE OR REPLACE FUNCTION pg_catalog.hawq_magma_status() RETURNS
+SETOF record LANGUAGE internal VOLATILE STRICT AS 'hawq_magma_status';
+
 ------------------------------------------------------------------
 -- magma format
 ------------------------------------------------------------------
-CREATE OR REPLACE FUNCTION pg_catalog.magma_validate_interfaces() RETURNS void
+DROP FUNCTION IF EXISTS pg_catalog.magma_validate_interfaces();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_validate_interfaces();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_validate_interfaces();
+DROP FUNCTION IF EXISTS pg_catalog.magma_validate_options();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_validate_options();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_validate_options();
+DROP FUNCTION IF EXISTS pg_catalog.magma_validate_encodings();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_validate_encodings();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_validate_encodings();
+DROP FUNCTION IF EXISTS pg_catalog.magma_validate_datatypes();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_validate_datatypes();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_validate_datatypes();
+DROP FUNCTION IF EXISTS pg_catalog.magma_createtable();
+DROP FUNCTION IF EXISTS pg_catalog.magma_droptable();
+DROP FUNCTION IF EXISTS pg_catalog.magma_createindex();
+DROP FUNCTION IF EXISTS pg_catalog.magma_dropindex();
+DROP FUNCTION IF EXISTS pg_catalog.magma_reindex_index();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_beginscan();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_getnext_init();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_getnext();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_rescan();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_endscan();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_stopscan();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_begindelete();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_delete();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_enddelete();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_beginupdate();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_update();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_endupdate();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_insert_init();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_insert();
+DROP FUNCTION IF EXISTS pg_catalog.magmatp_insert_finish();
+DROP FUNCTION IF EXISTS pg_catalog.magma_transaction();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_beginscan();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_getnext_init();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_getnext();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_rescan();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_endscan();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_stopscan();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_begindelete();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_delete();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_enddelete();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_beginupdate();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_update();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_endupdate();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_insert_init();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_insert();
+DROP FUNCTION IF EXISTS pg_catalog.magmaap_insert_finish();
+
+set gen_new_oid_value to 11004;
+CREATE FUNCTION pg_catalog.magma_validate_interfaces() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_interfaces'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_validate_interfaces() RETURNS void
+set gen_new_oid_value to 11005;
+CREATE FUNCTION pg_catalog.magmaap_validate_interfaces() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_interfaces'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_validate_interfaces() RETURNS void
+set gen_new_oid_value to 11006;
+CREATE FUNCTION pg_catalog.magmatp_validate_interfaces() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_interfaces'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_validate_options() RETURNS void
+set gen_new_oid_value to 11007;
+CREATE FUNCTION pg_catalog.magma_validate_options() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_options'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_validate_options() RETURNS void
+set gen_new_oid_value to 11008;
+CREATE FUNCTION pg_catalog.magmaap_validate_options() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_options'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_validate_options() RETURNS void
+set gen_new_oid_value to 11009;
+CREATE FUNCTION pg_catalog.magmatp_validate_options() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_options'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_validate_encodings() RETURNS void
+set gen_new_oid_value to 11010;
+CREATE FUNCTION pg_catalog.magma_validate_encodings() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_encodings'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_validate_encodings() RETURNS void
+set gen_new_oid_value to 11011;
+CREATE FUNCTION pg_catalog.magmaap_validate_encodings() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_encodings'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_validate_encodings() RETURNS void
+set gen_new_oid_value to 11012;
+CREATE FUNCTION pg_catalog.magmatp_validate_encodings() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_encodings'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_validate_datatypes() RETURNS void
+set gen_new_oid_value to 11013;
+CREATE FUNCTION pg_catalog.magma_validate_datatypes() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_datatypes'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_validate_datatypes() RETURNS void
+set gen_new_oid_value to 11014;
+CREATE FUNCTION pg_catalog.magmaap_validate_datatypes() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_datatypes'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_validate_datatypes() RETURNS void
+set gen_new_oid_value to 11015;
+CREATE FUNCTION pg_catalog.magmatp_validate_datatypes() RETURNS void
 AS '$libdir/magma.so', 'magma_validate_datatypes'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_createtable() RETURNS void
+set gen_new_oid_value to 11016;
+CREATE FUNCTION pg_catalog.magma_createtable() RETURNS void
 AS '$libdir/magma.so', 'magma_createtable'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_droptable() RETURNS void
+set gen_new_oid_value to 11017;
+CREATE FUNCTION pg_catalog.magma_droptable() RETURNS void
 AS '$libdir/magma.so', 'magma_droptable'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_createindex() RETURNS void
+set gen_new_oid_value to 11018;
+CREATE FUNCTION pg_catalog.magma_createindex() RETURNS void
 AS '$libdir/magma.so', 'magma_createindex'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_dropindex() RETURNS void
+set gen_new_oid_value to 11019;
+CREATE FUNCTION pg_catalog.magma_dropindex() RETURNS void
 AS '$libdir/magma.so', 'magma_dropindex'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_reindex_index() RETURNS void
+set gen_new_oid_value to 11020;
+CREATE FUNCTION pg_catalog.magma_reindex_index() RETURNS void
 AS '$libdir/magma.so', 'magma_reindex_index'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_beginscan() RETURNS bytea
+set gen_new_oid_value to 11021;
+CREATE FUNCTION pg_catalog.magmatp_beginscan() RETURNS bytea
 AS '$libdir/magma.so', 'magma_beginscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_getnext_init() RETURNS bytea
+set gen_new_oid_value to 11022;
+CREATE FUNCTION pg_catalog.magmatp_getnext_init() RETURNS bytea
 AS '$libdir/magma.so', 'magma_getnext_init'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_getnext() RETURNS bytea
+set gen_new_oid_value to 11023;
+CREATE FUNCTION pg_catalog.magmatp_getnext() RETURNS bytea
 AS '$libdir/magma.so', 'magma_getnext'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_rescan() RETURNS void
+set gen_new_oid_value to 11024;
+CREATE FUNCTION pg_catalog.magmatp_rescan() RETURNS void
 AS '$libdir/magma.so', 'magma_rescan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_endscan() RETURNS void
+set gen_new_oid_value to 11025;
+CREATE FUNCTION pg_catalog.magmatp_endscan() RETURNS void
 AS '$libdir/magma.so', 'magma_endscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_stopscan() RETURNS void
+set gen_new_oid_value to 11026;
+CREATE FUNCTION pg_catalog.magmatp_stopscan() RETURNS void
 AS '$libdir/magma.so', 'magma_stopscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_begindelete() RETURNS bytea
+set gen_new_oid_value to 11027;
+CREATE FUNCTION pg_catalog.magmatp_begindelete() RETURNS bytea
 AS '$libdir/magma.so', 'magma_begindelete'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_delete() RETURNS void
+set gen_new_oid_value to 11028;
+CREATE FUNCTION pg_catalog.magmatp_delete() RETURNS void
 AS '$libdir/magma.so', 'magma_delete'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_enddelete() RETURNS void
+set gen_new_oid_value to 11029;
+CREATE FUNCTION pg_catalog.magmatp_enddelete() RETURNS void
 AS '$libdir/magma.so', 'magma_enddelete'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_beginupdate() RETURNS bytea
+set gen_new_oid_value to 11030;
+CREATE FUNCTION pg_catalog.magmatp_beginupdate() RETURNS bytea
 AS '$libdir/magma.so', 'magma_beginupdate'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_update() RETURNS void
+set gen_new_oid_value to 11031;
+CREATE FUNCTION pg_catalog.magmatp_update() RETURNS void
 AS '$libdir/magma.so', 'magma_update'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_endupdate() RETURNS void
+set gen_new_oid_value to 11032;
+CREATE FUNCTION pg_catalog.magmatp_endupdate() RETURNS void
 AS '$libdir/magma.so', 'magma_endupdate'
 LANGUAGE C STABLE;
- 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_insert_init() RETURNS bytea
+
+set gen_new_oid_value to 11033;
+CREATE FUNCTION pg_catalog.magmatp_insert_init() RETURNS bytea
 AS '$libdir/magma.so', 'magma_insert_init'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_insert() RETURNS bytea
+set gen_new_oid_value to 11034;
+CREATE FUNCTION pg_catalog.magmatp_insert() RETURNS bytea
 AS '$libdir/magma.so', 'magma_insert'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmatp_insert_finish() RETURNS void
+set gen_new_oid_value to 11035;
+CREATE FUNCTION pg_catalog.magmatp_insert_finish() RETURNS void
 AS '$libdir/magma.so', 'magma_insert_finish'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_transaction() RETURNS void
+set gen_new_oid_value to 11036;
+CREATE FUNCTION pg_catalog.magma_transaction() RETURNS void
 AS '$libdir/magma.so', 'magma_transaction'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_beginscan() RETURNS bytea
+set gen_new_oid_value to 11037;
+CREATE FUNCTION pg_catalog.magmaap_beginscan() RETURNS bytea
 AS '$libdir/magma.so', 'magma_beginscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_getnext_init() RETURNS bytea
+set gen_new_oid_value to 11038;
+CREATE FUNCTION pg_catalog.magmaap_getnext_init() RETURNS bytea
 AS '$libdir/magma.so', 'magma_getnext_init'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_getnext() RETURNS bytea
+set gen_new_oid_value to 11039;
+CREATE FUNCTION pg_catalog.magmaap_getnext() RETURNS bytea
 AS '$libdir/magma.so', 'magma_getnext'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_rescan() RETURNS void
+set gen_new_oid_value to 11040;
+CREATE FUNCTION pg_catalog.magmaap_rescan() RETURNS void
 AS '$libdir/magma.so', 'magma_rescan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_endscan() RETURNS void
+set gen_new_oid_value to 11041;
+CREATE FUNCTION pg_catalog.magmaap_endscan() RETURNS void
 AS '$libdir/magma.so', 'magma_endscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_stopscan() RETURNS void
+set gen_new_oid_value to 11042;
+CREATE FUNCTION pg_catalog.magmaap_stopscan() RETURNS void
 AS '$libdir/magma.so', 'magma_stopscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_begindelete() RETURNS bytea
+set gen_new_oid_value to 11043;
+CREATE FUNCTION pg_catalog.magmaap_begindelete() RETURNS bytea
 AS '$libdir/magma.so', 'magma_begindelete'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_delete() RETURNS void
+set gen_new_oid_value to 11044;
+CREATE FUNCTION pg_catalog.magmaap_delete() RETURNS void
 AS '$libdir/magma.so', 'magma_delete'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_enddelete() RETURNS void
+set gen_new_oid_value to 11045;
+CREATE FUNCTION pg_catalog.magmaap_enddelete() RETURNS void
 AS '$libdir/magma.so', 'magma_enddelete'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_beginupdate() RETURNS bytea
+set gen_new_oid_value to 11046;
+CREATE FUNCTION pg_catalog.magmaap_beginupdate() RETURNS bytea
 AS '$libdir/magma.so', 'magma_beginupdate'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_update() RETURNS void
+set gen_new_oid_value to 11047;
+CREATE FUNCTION pg_catalog.magmaap_update() RETURNS void
 AS '$libdir/magma.so', 'magma_update'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_endupdate() RETURNS void
+set gen_new_oid_value to 11048;
+CREATE FUNCTION pg_catalog.magmaap_endupdate() RETURNS void
 AS '$libdir/magma.so', 'magma_endupdate'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_insert_init() RETURNS bytea
+set gen_new_oid_value to 11049;
+CREATE FUNCTION pg_catalog.magmaap_insert_init() RETURNS bytea
 AS '$libdir/magma.so', 'magma_insert_init'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_insert() RETURNS bytea
+set gen_new_oid_value to 11050;
+CREATE FUNCTION pg_catalog.magmaap_insert() RETURNS bytea
 AS '$libdir/magma.so', 'magma_insert'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magmaap_insert_finish() RETURNS void
+set gen_new_oid_value to 11051;
+CREATE FUNCTION pg_catalog.magmaap_insert_finish() RETURNS void
 AS '$libdir/magma.so', 'magma_insert_finish'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.magma_getstatus() RETURNS void
+set gen_new_oid_value to 11052;
+CREATE FUNCTION pg_catalog.magma_getstatus() RETURNS void
 AS '$libdir/magma.so', 'magma_getstatus'
 LANGUAGE C STABLE;
+
+reset gen_new_oid_value;
diff --git a/contrib/magma/monitor_install.sql b/contrib/magma/monitor_install.sql
index 1160e3b..f13072a 100644
--- a/contrib/magma/monitor_install.sql
+++ b/contrib/magma/monitor_install.sql
@@ -1,12 +1,6 @@
 ------------------------------------------------------------------
 -- hawq status
 ------------------------------------------------------------------
-CREATE FUNCTION pg_catalog.hawq_magma_status() RETURNS SETOF record LANGUAGE internal VOLATILE STRICT AS 'hawq_magma_status' WITH (OID=5085, DESCRIPTION="Return magma node information");
-
-CREATE OR REPLACE FUNCTION pg_catalog.magma_getstatus() RETURNS void
-AS '$libdir/magma.so', 'magma_getstatus'
-LANGUAGE C STABLE;
-
 CREATE VIEW pg_catalog.hawq_magma_status AS
     SELECT * FROM hawq_magma_status() AS s
     (node text,
diff --git a/contrib/orc/orc_install.sql b/contrib/orc/orc_install.sql
index 6baeefb..68c151a 100644
--- a/contrib/orc/orc_install.sql
+++ b/contrib/orc/orc_install.sql
@@ -5,81 +5,120 @@
 -- Support ORC format in pluggable storage framework
 --
 -- --------------------------------------------------------------------
+DROP FUNCTION IF EXISTS pg_catalog.orc_validate_interfaces();
+DROP FUNCTION IF EXISTS pg_catalog.orc_validate_options();
+DROP FUNCTION IF EXISTS pg_catalog.orc_validate_encodings();
+DROP FUNCTION IF EXISTS pg_catalog.orc_validate_datatypes();
+DROP FUNCTION IF EXISTS pg_catalog.orc_beginscan();
+DROP FUNCTION IF EXISTS pg_catalog.orc_getnext_init();
+DROP FUNCTION IF EXISTS pg_catalog.orc_getnext();
+DROP FUNCTION IF EXISTS pg_catalog.orc_rescan();
+DROP FUNCTION IF EXISTS pg_catalog.orc_endscan();
+DROP FUNCTION IF EXISTS pg_catalog.orc_stopscan();
+DROP FUNCTION IF EXISTS pg_catalog.orc_insert_init();
+DROP FUNCTION IF EXISTS pg_catalog.orc_insert();
+DROP FUNCTION IF EXISTS pg_catalog.orc_insert_finish();
+DROP FUNCTION IF EXISTS pg_catalog.hdfs_validate();
+DROP FUNCTION IF EXISTS pg_catalog.hdfs_blocklocation();
+DROP FUNCTION IF EXISTS pg_catalog.csv_in();
+DROP FUNCTION IF EXISTS pg_catalog.csv_out(record);
+DROP FUNCTION IF EXISTS pg_catalog.text_in();
+DROP FUNCTION IF EXISTS pg_catalog.text_out(record);
 
 SET allow_system_table_mods=ddl;
-  
-CREATE OR REPLACE FUNCTION pg_catalog.orc_validate_interfaces() RETURNS void
+set gen_new_oid_value to 10915;
+CREATE FUNCTION pg_catalog.orc_validate_interfaces() RETURNS void
 AS '$libdir/orc.so', 'orc_validate_interfaces'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_validate_options() RETURNS void
+set gen_new_oid_value to 10916;
+CREATE FUNCTION pg_catalog.orc_validate_options() RETURNS void
 AS '$libdir/orc.so', 'orc_validate_options'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_validate_encodings() RETURNS void
+set gen_new_oid_value to 10917;
+CREATE FUNCTION pg_catalog.orc_validate_encodings() RETURNS void
 AS '$libdir/orc.so', 'orc_validate_encodings'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_validate_datatypes() RETURNS void
+set gen_new_oid_value to 10918;
+CREATE FUNCTION pg_catalog.orc_validate_datatypes() RETURNS void
 AS '$libdir/orc.so', 'orc_validate_datatypes'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_beginscan() RETURNS bytea
+set gen_new_oid_value to 10919;
+CREATE FUNCTION pg_catalog.orc_beginscan() RETURNS bytea
 AS '$libdir/orc.so', 'orc_beginscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_getnext_init() RETURNS bytea
+set gen_new_oid_value to 10920;
+CREATE FUNCTION pg_catalog.orc_getnext_init() RETURNS bytea
 AS '$libdir/orc.so', 'orc_getnext_init'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_getnext() RETURNS bytea
+set gen_new_oid_value to 10921;
+CREATE FUNCTION pg_catalog.orc_getnext() RETURNS bytea
 AS '$libdir/orc.so', 'orc_getnext'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_rescan() RETURNS void
+set gen_new_oid_value to 10922;
+CREATE FUNCTION pg_catalog.orc_rescan() RETURNS void
 AS '$libdir/orc.so', 'orc_rescan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_endscan() RETURNS void
+set gen_new_oid_value to 10923;
+CREATE FUNCTION pg_catalog.orc_endscan() RETURNS void
 AS '$libdir/orc.so', 'orc_endscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_stopscan() RETURNS void
+set gen_new_oid_value to 10924;
+CREATE FUNCTION pg_catalog.orc_stopscan() RETURNS void
 AS '$libdir/orc.so', 'orc_stopscan'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_insert_init() RETURNS bytea
+set gen_new_oid_value to 10925;
+CREATE FUNCTION pg_catalog.orc_insert_init() RETURNS bytea
 AS '$libdir/orc.so', 'orc_insert_init'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_insert() RETURNS bytea
+set gen_new_oid_value to 10926;
+CREATE FUNCTION pg_catalog.orc_insert() RETURNS bytea
 AS '$libdir/orc.so', 'orc_insert'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.orc_insert_finish() RETURNS void
+set gen_new_oid_value to 10927;
+CREATE FUNCTION pg_catalog.orc_insert_finish() RETURNS void
 AS '$libdir/orc.so', 'orc_insert_finish'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.hdfs_validate() RETURNS void
+set gen_new_oid_value to 10906;
+CREATE FUNCTION pg_catalog.hdfs_validate() RETURNS void
 AS '$libdir/exthdfs.so', 'hdfsprotocol_validate'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.hdfs_blocklocation() RETURNS void
+set gen_new_oid_value to 10907;
+CREATE FUNCTION pg_catalog.hdfs_blocklocation() RETURNS void
 AS '$libdir/exthdfs.so', 'hdfsprotocol_blocklocation'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.csv_in() RETURNS record
+set gen_new_oid_value to 10910;
+CREATE FUNCTION pg_catalog.csv_in() RETURNS record
 AS '$libdir/extfmtcsv.so', 'extfmtcsv_in'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.csv_out(record) RETURNS bytea
+set gen_new_oid_value to 10911;
+CREATE FUNCTION pg_catalog.csv_out(record) RETURNS bytea
 AS '$libdir/extfmtcsv.so', 'extfmtcsv_out'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.text_in() RETURNS record
+set gen_new_oid_value to 10912;
+CREATE FUNCTION pg_catalog.text_in() RETURNS record
 AS '$libdir/extfmtcsv.so', 'extfmttext_in'
 LANGUAGE C STABLE;
 
-CREATE OR REPLACE FUNCTION pg_catalog.text_out(record) RETURNS bytea
+set gen_new_oid_value to 10913;
+CREATE FUNCTION pg_catalog.text_out(record) RETURNS bytea
 AS '$libdir/extfmtcsv.so', 'extfmttext_out'
 LANGUAGE C STABLE;
+
+reset gen_new_oid_value;
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index fd238b1..a275029 100755
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -119,11 +119,12 @@ and subpartition_element is:
 where storage_parameter is:
    APPENDONLY={TRUE|FALSE}
    BLOCKSIZE={8192-2097152}
-   ORIENTATION={PARQUET|ROW}
-   COMPRESSTYPE={ZLIB|SNAPPY|GZIP|NONE}
+   ORIENTATION={PARQUET|ROW|ORC}
+   COMPRESSTYPE={ZLIB|SNAPPY|GZIP|LZ4|NONE}
    COMPRESSLEVEL={0-9}
    FILLFACTOR={10-100}
    OIDS[=TRUE|FALSE]
+   DICTHRESHOLD={0-1}
 
 where storage_directive is:
    COMPRESSTYPE={ZLIB|SNAPPY|GZIP|NONE} 
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 60557d8..b887d34 100755
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -129,13 +129,14 @@ where storage_parameter for a table is:
    APPENDONLY={TRUE}
    BLOCKSIZE={8192-2097152}
    bucketnum={<x>}
-   ORIENTATION={ROW | PARQUET}
-   COMPRESSTYPE={ZLIB | SNAPPY | GZIP | NONE}
+   ORIENTATION={ROW | PARQUET | ORC}
+   COMPRESSTYPE={ZLIB | SNAPPY | GZIP | LZ4 | NONE}
    COMPRESSLEVEL={0-9}
    FILLFACTOR={10-100}
    OIDS=[TRUE|FALSE]
    PAGESIZE={1024-1073741823}
    ROWGROUPSIZE={1024-1073741823}
+   DICTHRESHOLD={0-1}
 
 and table_constraint is:
    [CONSTRAINT constraint_name]
@@ -196,13 +197,14 @@ where <storage_parameter> for a partition is:
 
    APPENDONLY={TRUE}
    BLOCKSIZE={8192-2097152}
-   ORIENTATION={ROW | PARQUET}
-   COMPRESSTYPE={ZLIB | SNAPPY | GZIP | NONE}
+   ORIENTATION={ROW | PARQUET | ORC}
+   COMPRESSTYPE={ZLIB | SNAPPY | GZIP | LZ4 | NONE}
    COMPRESSLEVEL={0-9}
    FILLFACTOR={10-100}
    OIDS=[TRUE|FALSE]
    PAGESIZE={1024-1073741823}
    ROWGROUPSIZE={1024-1073741823}
+   DICTHRESHOLD={0-1}
 </synopsis>
 
 
diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml
index 87d4f72..9553ce7 100755
--- a/doc/src/sgml/ref/create_table_as.sgml
+++ b/doc/src/sgml/ref/create_table_as.sgml
@@ -54,11 +54,12 @@ where storage_parameter is:
 
    APPENDONLY={TRUE|FALSE}
    BLOCKSIZE={8192-2097152}
-   ORIENTATION={PARQUET|ROW}
-   COMPRESSTYPE={ZLIB|SNAPPY|GZIP|NONE}
+   ORIENTATION={PARQUET|ROW|ORC}
+   COMPRESSTYPE={ZLIB|SNAPPY|GZIP|LZ4|NONE}
    COMPRESSLEVEL={0-9}
    FILLFACTOR={10-100}
    OIDS[=TRUE|FALSE]
+   DICTHRESHOLD={0-1}
 
 
 </synopsis>
diff --git a/src/backend/access/bitmap/bitmapattutil.c b/src/backend/access/bitmap/bitmapattutil.c
index 3b6418d..74df331 100644
--- a/src/backend/access/bitmap/bitmapattutil.c
+++ b/src/backend/access/bitmap/bitmapattutil.c
@@ -192,6 +192,7 @@ _bitmap_create_lov_heapandindex(Relation rel,
 	indattrs = tupDesc->natts - 2;
 	indexInfo = makeNode(IndexInfo);
 	indexInfo->ii_NumIndexAttrs = indattrs;
+	indexInfo->ii_NumIndexKeyAttrs = indattrs;
 	indexInfo->ii_Expressions = NIL;
 	indexInfo->ii_ExpressionsState = NIL;
 	indexInfo->ii_Predicate = make_ands_implicit(NULL);
diff --git a/src/backend/access/external/url_curl.c b/src/backend/access/external/url_curl.c
index 1fc2829..eb57960 100644
--- a/src/backend/access/external/url_curl.c
+++ b/src/backend/access/external/url_curl.c
@@ -1241,12 +1241,22 @@ URL_FILE *url_curl_fopen(char *url, bool forwrite, extvar_t *ev,
     fill_buffer(file, 1);
 
     /* check the connection for GET request */
-    if (check_response(file, &response_code, &response_string))
-      ereport(ERROR,
-              (errcode(ERRCODE_CONNECTION_FAILURE),
-               errmsg("could not open \"%s\" for reading", file->url),
-               errdetail("Unexpected response from gpfdist server: %d - %s",
-                         response_code, response_string)));
+    // if connection is established, http_response should not be null
+    if (file->u.curl.still_running > 0 || file->u.curl.http_response == 0) {
+      if (check_response(file, &response_code, &response_string))
+        ereport(ERROR,
+                (errcode(ERRCODE_CONNECTION_FAILURE),
+                 errmsg("could not open \"%s\" for reading", file->url),
+                 errdetail("Unexpected response from gpfdist server: %d - %s",
+                           response_code, response_string)));
+    }
+    if (file->u.curl.still_running == 0) {
+      elog(LOG,
+           "session closed when checking the connection in url_curl_fopen, "
+           "http_response = \"%s\".",
+           file->u.curl.http_response);
+    }
+
   } else {
     /* use empty message */
     CURL_EASY_SETOPT(file->u.curl.handle, CURLOPT_POSTFIELDS, "");
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index c1567e1..240cb51 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -704,7 +704,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2)
 				load1;
 	TupleDesc	tupdes = RelationGetDescr(wstate->index);
 	int			i,
-				keysz = RelationGetNumberOfAttributes(wstate->index);
+				keysz = IndexRelationGetNumberOfKeyAttributes(wstate->index);
 	ScanKey		indexScanKey = NULL;
 
 	if (merge)
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index dfe6e21..460ec8e 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -48,7 +48,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
 	int			i;
 
 	itupdesc = RelationGetDescr(rel);
-	natts = RelationGetNumberOfAttributes(rel);
+	natts = IndexRelationGetNumberOfKeyAttributes(rel);
 
 	skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
 
@@ -94,7 +94,7 @@ _bt_mkscankey_nodata(Relation rel)
 	int			natts;
 	int			i;
 
-	natts = RelationGetNumberOfAttributes(rel);
+	natts = IndexRelationGetNumberOfKeyAttributes(rel);
 
 	skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
 
diff --git a/src/backend/access/orc/orcam.c b/src/backend/access/orc/orcam.c
index f1d4f02..df7242e 100644
--- a/src/backend/access/orc/orcam.c
+++ b/src/backend/access/orc/orcam.c
@@ -121,8 +121,7 @@ static void checkOrcError(OrcFormatData *orcFormatData) {
     ORCFormatCatchedError errBuf = *e;
     ORCFormatFreeORCFormatC(&orcFormatData->fmt);
     ORCFormatFreeStorageFormatC(&orcFormatData->updateDeleteFmt);
-    ereport(ERROR,
-            (errcode(errBuf.errCode), errmsg("%s", errBuf.errMessage)));
+    ereport(ERROR, (errcode(errBuf.errCode), errmsg("%s", errBuf.errMessage)));
   }
 }
 
@@ -245,7 +244,8 @@ static void convertAndFillIntoOrcFormatData(OrcFormatData *orcFormatData,
     } else if (dataType == HAWQ_TYPE_NUMERIC) {
       Numeric num = DatumGetNumeric(values[i]);
       orcFormatData->colRawValues[i] = (char *)num;
-      if (NUMERIC_IS_NAN(num)) nulls[i] = true;
+      if (NUMERIC_IS_NAN(num))
+        nulls[i] = true;
     }
   }
 }
@@ -337,7 +337,8 @@ OrcScanDescData *orcBeginRead(Relation rel, Snapshot snapshot, TupleDesc desc,
 
   RelationIncrementReferenceCount(rel);
 
-  if (desc == NULL) desc = RelationGetDescr(rel);
+  if (desc == NULL)
+    desc = RelationGetDescr(rel);
 
   scanDesc->rel = rel;
   orcFormatData->fmt = ORCFormatNewORCFormatC("{}", 0);
@@ -356,7 +357,8 @@ OrcScanDescData *orcBeginRead(Relation rel, Snapshot snapshot, TupleDesc desc,
                           splits[i].fileName);
   }
 
-  if (splitCount > 0) addFilesystemCredential(splits[0].fileName);
+  if (splitCount > 0)
+    addFilesystemCredential(splits[0].fileName);
 
   void *qualList = NULL;
   CommonPlanContext ctx;
@@ -374,7 +376,8 @@ OrcScanDescData *orcBeginRead(Relation rel, Snapshot snapshot, TupleDesc desc,
 
   ItemPointerSetInvalid(&scanDesc->cdb_fake_ctid);
 
-  for (int32 i = 0; i < splitCount; ++i) pfree(splits[i].fileName);
+  for (int32 i = 0; i < splitCount; ++i)
+    pfree(splits[i].fileName);
   pfree(splits);
 
   return scanDesc;
@@ -395,60 +398,55 @@ void orcReadNext(OrcScanDescData *scanData, TupleTableSlot *slot) {
   checkOrcError(orcFormatData);
   if (res) {
     for (int32_t i = 0; i < orcFormatData->numberOfColumns; ++i) {
-      if (nulls[i]) continue;
+      if (nulls[i])
+        continue;
 
       switch (tupleDesc->attrs[i]->atttypid) {
-        case HAWQ_TYPE_BOOL: {
-          values[i] = BoolGetDatum(*(bool *)(orcFormatData->colRawValues[i]));
-          break;
-        }
-        case HAWQ_TYPE_INT2: {
-          values[i] =
-              Int16GetDatum(*(int16_t *)(orcFormatData->colRawValues[i]));
-          break;
-        }
-        case HAWQ_TYPE_INT4: {
-          values[i] =
-              Int32GetDatum(*(int32_t *)(orcFormatData->colRawValues[i]));
-          break;
-        }
-        case HAWQ_TYPE_INT8:
-        case HAWQ_TYPE_TIME:
-        case HAWQ_TYPE_TIMESTAMP:
-        case HAWQ_TYPE_TIMESTAMPTZ: {
-          values[i] =
-              Int64GetDatum(*(int64_t *)(orcFormatData->colRawValues[i]));
-          break;
-        }
-        case HAWQ_TYPE_FLOAT4: {
-          values[i] =
-              Float4GetDatum(*(float *)(orcFormatData->colRawValues[i]));
-          break;
-        }
-        case HAWQ_TYPE_FLOAT8: {
-          values[i] =
-              Float8GetDatum(*(double *)(orcFormatData->colRawValues[i]));
-          break;
-        }
-        case HAWQ_TYPE_VARCHAR:
-        case HAWQ_TYPE_TEXT:
-        case HAWQ_TYPE_BPCHAR:
-        case HAWQ_TYPE_BYTE:
-        case HAWQ_TYPE_NUMERIC: {
-          SET_VARSIZE((struct varlena *)(orcFormatData->colRawValues[i]),
-                      orcFormatData->colValLength[i]);
-          values[i] = PointerGetDatum(orcFormatData->colRawValues[i]);
-          break;
-        }
-        case HAWQ_TYPE_DATE: {
-          values[i] =
-              Int32GetDatum(*(int32_t *)(orcFormatData->colRawValues[i]) -
-                            POSTGRES_EPOCH_JDATE + UNIX_EPOCH_JDATE);
-          break;
-        }
-        default: {
-          break;
-        }
+      case HAWQ_TYPE_BOOL: {
+        values[i] = BoolGetDatum(*(bool *)(orcFormatData->colRawValues[i]));
+        break;
+      }
+      case HAWQ_TYPE_INT2: {
+        values[i] = Int16GetDatum(*(int16_t *)(orcFormatData->colRawValues[i]));
+        break;
+      }
+      case HAWQ_TYPE_INT4: {
+        values[i] = Int32GetDatum(*(int32_t *)(orcFormatData->colRawValues[i]));
+        break;
+      }
+      case HAWQ_TYPE_INT8:
+      case HAWQ_TYPE_TIME:
+      case HAWQ_TYPE_TIMESTAMP:
+      case HAWQ_TYPE_TIMESTAMPTZ: {
+        values[i] = Int64GetDatum(*(int64_t *)(orcFormatData->colRawValues[i]));
+        break;
+      }
+      case HAWQ_TYPE_FLOAT4: {
+        values[i] = Float4GetDatum(*(float *)(orcFormatData->colRawValues[i]));
+        break;
+      }
+      case HAWQ_TYPE_FLOAT8: {
+        values[i] = Float8GetDatum(*(double *)(orcFormatData->colRawValues[i]));
+        break;
+      }
+      case HAWQ_TYPE_VARCHAR:
+      case HAWQ_TYPE_TEXT:
+      case HAWQ_TYPE_BPCHAR:
+      case HAWQ_TYPE_BYTE:
+      case HAWQ_TYPE_NUMERIC: {
+        SET_VARSIZE((struct varlena *)(orcFormatData->colRawValues[i]),
+                    orcFormatData->colValLength[i]);
+        values[i] = PointerGetDatum(orcFormatData->colRawValues[i]);
+        break;
+      }
+      case HAWQ_TYPE_DATE: {
+        values[i] = Int32GetDatum(*(int32_t *)(orcFormatData->colRawValues[i]) -
+                                  POSTGRES_EPOCH_JDATE + UNIX_EPOCH_JDATE);
+        break;
+      }
+      default: {
+        break;
+      }
       }
     }
     TupSetVirtualTupleNValid(slot, slot->tts_tupleDescriptor->natts);
@@ -486,13 +484,15 @@ retry:
   ret = FileRead(file, buf + nRead, amount - nRead);
   if (ret > 0) {
     nRead += ret;
-    if (nRead < amount) goto retry;
+    if (nRead < amount)
+      goto retry;
   } else if (ret < 0) {
-    if (errno == EINTR) goto retry;
+    if (errno == EINTR)
+      goto retry;
     ereport(ERROR, (errcode_for_file_access(),
                     errmsg("could not read file \"%s\": %m", path),
                     errdetail("%s", HdfsGetLastError())));
-  } else {  // EOF
+  } else { // EOF
   }
   return nRead;
 }
@@ -504,7 +504,8 @@ retry:
   ret = FileWrite(file, buf + nWrite, amount - nWrite);
   if (ret >= 0) {
     nWrite += ret;
-    if (nWrite < amount) goto retry;
+    if (nWrite < amount)
+      goto retry;
   } else {
     ereport(ERROR, (errcode_for_file_access(),
                     errmsg("could not read file \"%s\": %m", path),
@@ -548,12 +549,14 @@ static void orcCopyInternal(const char *srcPath, int64 eof,
 }
 
 static bool orcCopy(const char *name, tOffset size, void *arg) {
-  if (size == 0) return false;
+  if (size == 0)
+    return false;
 
   OrcCopyContext *ctx = (OrcCopyContext *)arg;
   char *ptr = strrchr(name, '/');
   int32 segno = pg_atoi(ptr + 1, sizeof(int), 0);
-  if (list_member_int(ctx->segNoList, segno)) return false;
+  if (list_member_int(ctx->segNoList, segno))
+    return false;
 
   sprintf(ctx->srcFile, "%s/%u", ctx->srcDir, segno);
   sprintf(ctx->destFile, "%s/%u", ctx->destDir, segno);
@@ -578,7 +581,8 @@ static void copyFileForDirectDispatch(Oid relId, int32 targetSegNo,
 
   ListCell *cell = NULL;
   foreach (cell, segNoList) {
-    if (lfirst_int(cell) == targetSegNo) continue;
+    if (lfirst_int(cell) == targetSegNo)
+      continue;
 
     QueryContextDispatchingSendBack sendback =
         CreateQueryContextDispatchingSendBack(1);
@@ -605,7 +609,8 @@ static void copyFileForDirectDispatch(Oid relId, int32 targetSegNo,
   pfree(ctx.destFile);
   pfree(ctx.srcFile);
   pfree(ctx.buffer);
-  if (segNoList) pfree(segNoList);
+  if (segNoList)
+    pfree(segNoList);
 }
 
 OrcDeleteDescData *orcBeginDelete(Relation rel, List *fileSplits,
@@ -678,7 +683,8 @@ OrcDeleteDescData *orcBeginDelete(Relation rel, List *fileSplits,
     pfree(oldPath);
   }
 
-  for (int32 i = 0; i < splitCount; ++i) pfree(splits[i].fileName);
+  for (int32 i = 0; i < splitCount; ++i)
+    pfree(splits[i].fileName);
   pfree(splits);
   pfree(basePath);
   pfree(hdfsPath);
@@ -796,7 +802,8 @@ OrcUpdateDescData *orcBeginUpdate(Relation rel, List *fileSplits,
     pfree(oldPath);
   }
 
-  for (int32 i = 0; i < splitCount; ++i) pfree(splits[i].fileName);
+  for (int32 i = 0; i < splitCount; ++i)
+    pfree(splits[i].fileName);
   pfree(splits);
   pfree(basePath);
   pfree(hdfsPath);
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index b5cf718..94be0d3 100755
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -441,9 +441,23 @@ Boot_InsertStmt:
 Boot_DeclareIndexStmt:
 		  XDECLARE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
 				{
+					IndexStmt *stmt = makeNode(IndexStmt);
 					Oid     relationId;
 					do_start();
 
+					stmt->idxname = $3;
+					stmt->relation = makeRangeVar(NULL, NULL, LexIDStr($6), -1);
+					stmt->accessMethod = $8;
+					stmt->tableSpace = NULL;
+					stmt->indexParams = $10;
+					stmt->indexIncludingParams = NIL;
+					stmt->options = NIL;
+					stmt->whereClause = NULL;
+					stmt->unique = false;
+					stmt->primary = false;
+					stmt->isconstraint = false;
+					stmt->concurrent = false;
+
 					relationId = RangeVarGetRelid(makeRangeVar(NULL, NULL, LexIDStr($6), -1), 
 								false, false);
 
@@ -456,7 +470,7 @@ Boot_DeclareIndexStmt:
 								NULL, NIL, NIL,
 								false, false, false,
 								false, false, true, false, false,
-								false, NULL);
+								false, stmt);
 					do_end();
 				}
 		;
@@ -464,9 +478,23 @@ Boot_DeclareIndexStmt:
 Boot_DeclareUniqueIndexStmt:
 		  XDECLARE UNIQUE INDEX boot_ident oidspec ON boot_ident USING boot_ident LPAREN boot_index_params RPAREN
 				{
+					IndexStmt *stmt = makeNode(IndexStmt);
 					Oid     relationId;
 					do_start();
 
+					stmt->idxname = $4;
+					stmt->relation = makeRangeVar(NULL, NULL, LexIDStr($7), -1);
+					stmt->accessMethod = $9;
+					stmt->tableSpace = NULL;
+					stmt->indexParams = $11;
+					stmt->indexIncludingParams = NIL;
+					stmt->options = NIL;
+					stmt->whereClause = NULL;
+					stmt->unique = true;
+					stmt->primary = false;
+					stmt->isconstraint = false;
+					stmt->concurrent = false;
+
 					relationId = RangeVarGetRelid(makeRangeVar(NULL, NULL, LexIDStr($7), -1),
 								false, false);
                                                   
@@ -480,7 +508,7 @@ Boot_DeclareUniqueIndexStmt:
 								true, false, false,
 								false, false, true, false, false,
 								false,
-								NULL);
+								stmt);
 					do_end();
 				}
 		;
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 8c81bb1..f8302e9 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -150,9 +150,8 @@ ifeq ($(with_orc), yes)
 	$(INSTALL_DATA) $(srcdir)/../../../contrib/orc/orc_install.sql '$(DESTDIR)$(datadir)/orc_install.sql'
 	$(INSTALL_DATA) $(srcdir)/../../../contrib/orc/hive_install.sql '$(DESTDIR)$(datadir)/hive_install.sql'
 	$(INSTALL_DATA) $(srcdir)/../../../contrib/orc/orc_uninstall.sql '$(DESTDIR)$(datadir)/orc_uninstall.sql'
-	$(INSTALL_SCRIPT) $(srcdir)/../../../contrib/oushu/orc_debug_metadata.py '$(DESTDIR)$(bindir)/orc_debug_metadata.py'
-	$(INSTALL_SCRIPT) $(srcdir)/../../../contrib/oushu/orc_debug_statistics.py '$(DESTDIR)$(bindir)/orc_debug_statistics.py'
-	$(INSTALL_DATA) $(srcdir)/../../../contrib/oushu/load_orc_debug_udf.sql '$(DESTDIR)$(datadir)/load_orc_debug_udf.sql'
+	$(INSTALL_SCRIPT) $(srcdir)/../../../contrib/hornet/orc_debug_metadata.py '$(DESTDIR)$(bindir)/orc_debug_metadata.py'
+	$(INSTALL_SCRIPT) $(srcdir)/../../../contrib/hornet/orc_debug_statistics.py '$(DESTDIR)$(bindir)/orc_debug_statistics.py'
 endif
 	$(INSTALL_DATA) $(srcdir)/sql_features.txt '$(DESTDIR)$(datadir)/sql_features.txt'
 	$(INSTALL_DATA) $(call vpathsearch,gp_toolkit.sql) '$(DESTDIR)$(datadir)/gp_toolkit.sql'
diff --git a/src/backend/catalog/aoseg.c b/src/backend/catalog/aoseg.c
index 10b524e..b7b93fd 100644
--- a/src/backend/catalog/aoseg.c
+++ b/src/backend/catalog/aoseg.c
@@ -259,6 +259,7 @@ create_aoseg_table(Relation rel, Oid aosegOid, Oid aosegIndexOid, Oid * comptype
 	 */
 	indexInfo = makeNode(IndexInfo);
 	indexInfo->ii_NumIndexAttrs = 1;
+	indexInfo->ii_NumIndexKeyAttrs = 1;
 	indexInfo->ii_KeyAttrNumbers[0] = 1;
 	indexInfo->ii_Expressions = NIL;
 	indexInfo->ii_ExpressionsState = NIL;
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 76e9c91..e7e3887 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -2986,6 +2986,7 @@ StoreRelCheck(Relation rel, char *ccname, char *ccbin, Oid conOid)
 								   RelationGetRelid(rel),		/* relation */
 								   attNos,		/* attrs in the constraint */
 								   keycount,		/* # attrs in the constraint */
+								   keycount,
 								   InvalidOid,	/* not a domain constraint */
 								   InvalidOid,	/* Foreign key fields */
 								   NULL,
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9370eb4..9b4762e 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -419,9 +419,9 @@ UpdateIndexRelation(Oid indexoid,
 	 * caller pass them like this to start with?)
 	 */
 	indkey = buildint2vector(NULL, indexInfo->ii_NumIndexAttrs);
-	indclass = buildoidvector(classOids, indexInfo->ii_NumIndexAttrs);
 	for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
 		indkey->values[i] = indexInfo->ii_KeyAttrNumbers[i];
+	indclass = buildoidvector(classOids, indexInfo->ii_NumIndexKeyAttrs);
 
 	/*
 	 * Convert the index expressions (if any) to a text datum
@@ -468,6 +468,7 @@ UpdateIndexRelation(Oid indexoid,
 	values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
 	values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
 	values[Anum_pg_index_indnatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexAttrs);
+	values[Anum_pg_index_indnkeyatts - 1] = Int16GetDatum(indexInfo->ii_NumIndexKeyAttrs);
 	values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
 	values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
 	values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
@@ -812,6 +813,7 @@ index_create(Oid heapRelationId,
 											   heapRelationId,
 											   indexInfo->ii_KeyAttrNumbers,
 											   indexInfo->ii_NumIndexAttrs,
+											   indexInfo->ii_NumIndexKeyAttrs,
 											   InvalidOid,	/* no domain */
 											   InvalidOid,	/* no foreign key */
 											   NULL,
@@ -870,7 +872,7 @@ index_create(Oid heapRelationId,
 		}
 
 		/* Store dependency on operator classes */
-		for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
+		for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++)
 		{
 			referenced.classId = OperatorClassRelationId;
 			referenced.objectId = classObjectId[i];
@@ -917,6 +919,7 @@ index_create(Oid heapRelationId,
 	else
 		Assert(indexRelation->rd_indexcxt != NULL);
 
+	indexRelation->rd_index->indnkeyatts = indexInfo->ii_NumIndexKeyAttrs;
 	/*
 	 * For upgrade, if we've already created the index in another database,
 	 * we don't need or want to recreate it.
@@ -993,6 +996,7 @@ index_create(Oid heapRelationId,
 		MagmaIndexInfo idxinfo;
 		idxinfo.indexName = indexRelationName;
 		idxinfo.indexType = DEFAULT_INDEX_TYPE;
+		idxinfo.keynums = indexInfo->ii_NumIndexKeyAttrs;
 		idxinfo.primary = isprimary;
 		idxinfo.unique = indexInfo->ii_Unique;
 		idxinfo.indkey = buildint2vector(NULL, indexInfo->ii_NumIndexAttrs);
@@ -1128,6 +1132,7 @@ ext_constraint_create(Oid extRelationId,
 		                                  extRelationId,
 		                                  constraintInfo->ii_KeyAttrNumbers,
 		                                  constraintInfo->ii_NumIndexAttrs,
+		                                  constraintInfo->ii_NumIndexKeyAttrs,
 		                                  InvalidOid,	/* no domain */
 		                                  InvalidOid,	/* no foreign key */
 		                                  NULL,
@@ -1327,15 +1332,18 @@ BuildIndexInfo(Relation index)
 	IndexInfo  *ii = makeNode(IndexInfo);
 	Form_pg_index indexStruct = index->rd_index;
 	int			i;
-	int			numKeys;
+	int			numAtts;
 
 	/* check the number of keys, and copy attr numbers into the IndexInfo */
-	numKeys = indexStruct->indnatts;
-	if (numKeys < 1 || numKeys > INDEX_MAX_KEYS)
+	numAtts = indexStruct->indnatts;
+	if (numAtts < 1 || numAtts > INDEX_MAX_KEYS)
 		elog(ERROR, "invalid indnatts %d for index %u",
-			 numKeys, RelationGetRelid(index));
-	ii->ii_NumIndexAttrs = numKeys;
-	for (i = 0; i < numKeys; i++)
+		     numAtts, RelationGetRelid(index));
+	ii->ii_NumIndexAttrs = numAtts;
+	ii->ii_NumIndexKeyAttrs = indexStruct->indnkeyatts;
+	Assert(ii->ii_NumIndexKeyAttrs != 0);
+	Assert(ii->ii_NumIndexKeyAttrs <= ii->ii_NumIndexAttrs);
+	for (i = 0; i < numAtts; i++)
 		ii->ii_KeyAttrNumbers[i] = indexStruct->indkey.values[i];
 
 	/* fetch any expressions needed for expressional indexes */
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index f1e6126..f9433f4 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -107,6 +107,7 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
 		 */
 		Assert(indexInfo->ii_Expressions == NIL);
 		Assert(indexInfo->ii_Predicate == NIL);
+		Assert(indexInfo->ii_NumIndexKeyAttrs != 0);
 
 		/*
 		 * FormIndexDatum fills in its values and isnull parameters with the
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 0a87b63..ca19b5f 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -51,6 +51,7 @@ CreateConstraintEntry(const char *constraintName,
 					  Oid relId,
 					  const int16 *constraintKey,
 					  int constraintNKeys,
+					  int constraintNTotalKeys,
 					  Oid domainId,
 					  Oid foreignRelId,
 					  const int16 *foreignKey,
@@ -84,14 +85,14 @@ CreateConstraintEntry(const char *constraintName,
 	/*
 	 * Convert C arrays into Postgres arrays.
 	 */
-	if (constraintNKeys > 0)
+	if (constraintNTotalKeys > 0)
 	{
 		Datum	   *conkey;
 
-		conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));
-		for (i = 0; i < constraintNKeys; i++)
+		conkey = (Datum *) palloc(constraintNTotalKeys * sizeof(Datum));
+		for (i = 0; i < constraintNTotalKeys; i++)
 			conkey[i] = Int16GetDatum(constraintKey[i]);
-		conkeyArray = construct_array(conkey, constraintNKeys,
+		conkeyArray = construct_array(conkey, constraintNTotalKeys,
 									  INT2OID, 2, true, 's');
 	}
 	else
@@ -180,9 +181,9 @@ CreateConstraintEntry(const char *constraintName,
 
 		relobject.classId = RelationRelationId;
 		relobject.objectId = relId;
-		if (constraintNKeys > 0)
+		if (constraintNTotalKeys > 0)
 		{
-			for (i = 0; i < constraintNKeys; i++)
+			for (i = 0; i < constraintNTotalKeys; i++)
 			{
 				relobject.objectSubId = constraintKey[i];
 
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index aaf19a2..439abfb 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -322,6 +322,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 
 	indexInfo = makeNode(IndexInfo);
 	indexInfo->ii_NumIndexAttrs = 2;
+	indexInfo->ii_NumIndexKeyAttrs = 2;
 	indexInfo->ii_KeyAttrNumbers[0] = 1;
 	indexInfo->ii_KeyAttrNumbers[1] = 2;
 	indexInfo->ii_Expressions = NIL;
diff --git a/src/backend/cdb/cdbmutate.c b/src/backend/cdb/cdbmutate.c
index 73239dd..804edf2 100644
--- a/src/backend/cdb/cdbmutate.c
+++ b/src/backend/cdb/cdbmutate.c
@@ -1479,7 +1479,7 @@ isAnyIndexColChangedByUpdate(Index resultRelation, Plan *plan, Relation relation
 	{
 		Form_pg_index index = (Form_pg_index) GETSTRUCT(htup);
 		bool colChange = isAnyColChangedByUpdate(resultRelation, plan->targetlist,
-																						 index->indnatts, index->indkey.values);
+																						 index->indnkeyatts, index->indkey.values);
 		if (colChange) {
 			caql_endscan(pcqCtx);
 			heap_close(indrel, AccessShareLock);
diff --git a/src/backend/cdb/cdbpartition.c b/src/backend/cdb/cdbpartition.c
index 49bf45e..3eb57d6 100644
--- a/src/backend/cdb/cdbpartition.c
+++ b/src/backend/cdb/cdbpartition.c
@@ -8139,6 +8139,7 @@ constraint_apply_mapped(HeapTuple tuple, AttrMap *map, Relation cand,
 								  RelationGetRelid(cand),
 								  keys,
 								  nkeys,
+								  nkeys,
 								  InvalidOid,
 								  InvalidOid,
 								  NULL,
@@ -8186,6 +8187,7 @@ constraint_apply_mapped(HeapTuple tuple, AttrMap *map, Relation cand,
 								  RelationGetRelid(cand),
 								  keys,
 								  nkeys,
+								  nkeys,
 								  InvalidOid,
 								  con->confrelid,
 								  fkeys,
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 5c0fcc1..7d43c8f 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -166,6 +166,7 @@ DefineIndex(Oid relationId,
 	Datum		reloptions;
 	IndexInfo  *indexInfo;
 	int			numberOfAttributes;
+	int     numberOfKeyAttributes;
 	List	   *old_xact_list;
 	ListCell   *lc;
 	uint32		ixcnt;
@@ -184,10 +185,28 @@ DefineIndex(Oid relationId,
 	cqContext  *amcqCtx;
 	cqContext  *attcqCtx;
 
+	if (list_intersection(stmt->indexParams, stmt->indexIncludingParams) != NIL)
+	  ereport(ERROR,
+	          (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+	              errmsg("included columns must not intersect with key columns")));
+
+	/*
+	 * count key attributes in index
+	 */
+	numberOfKeyAttributes = list_length(stmt->indexParams);
+
 	/*
-	 * count attributes in index
+	 * We append any INCLUDE columns onto the indexParams list so that we have
+	 * one list with all columns.  Later we can determine which of these are
+	 * key columns, and which are just part of the INCLUDE list by checking
+	 * the list position.  A list item in a position less than
+	 * ii_NumIndexKeyAttrs is part of the key columns, and anything equal to
+	 * and over is part of the INCLUDE columns.
 	 */
-	numberOfAttributes = list_length(attributeList);
+	stmt->indexParams = list_concat(stmt->indexParams,
+	                                stmt->indexIncludingParams);
+	numberOfAttributes = list_length(stmt->indexParams);
+
 	if (numberOfAttributes <= 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
@@ -214,13 +233,6 @@ DefineIndex(Oid relationId,
 
 	relationId = RelationGetRelid(rel);
 	namespaceId = RelationGetNamespace(rel);
-
-	/*
-	if(RelationIsExternal(rel))
-		ereport(ERROR,
-				(errcode(ERRCODE_GP_FEATURE_NOT_SUPPORTED),
-				 errmsg("cannot create indexes on external tables.")));
-	*/
 		
 	/* Note: during bootstrap may see uncataloged relation */
 	if (rel->rd_rel->relkind != RELKIND_RELATION &&
@@ -553,6 +565,7 @@ DefineIndex(Oid relationId,
 	 */
 	indexInfo = makeNode(IndexInfo);
 	indexInfo->ii_NumIndexAttrs = numberOfAttributes;
+	indexInfo->ii_NumIndexKeyAttrs = numberOfKeyAttributes;
 	indexInfo->ii_Expressions = NIL;	/* for now */
 	indexInfo->ii_ExpressionsState = NIL;
 	indexInfo->ii_Predicate = make_ands_implicit(predicate);
@@ -562,7 +575,7 @@ DefineIndex(Oid relationId,
 	indexInfo->opaque = (void*)palloc0(sizeof(IndexInfoOpaque));
 
 	classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid));
-	ComputeIndexAttrs(indexInfo, classObjectId, attributeList,
+	ComputeIndexAttrs(indexInfo, classObjectId, stmt->indexParams,
 					  relationId, accessMethodName, accessMethodId,
 					  isconstraint);
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 2b46e25..3460af4 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -9261,6 +9261,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
 									  RelationGetRelid(rel),
 									  fkattnum,
 									  numfks,
+									  numfks,
 									  InvalidOid,		/* not a domain
 														 * constraint */
 									  RelationGetRelid(pkrel),
@@ -19615,6 +19616,7 @@ void InvokeMagmaCreateIndex(FmgrInfo *func,
 	psdata.magma_idx.unique = index->unique;
 	int idxCount = index->indkey->dim1;
 	psdata.magma_idx.colCount = idxCount;
+	psdata.magma_idx.keynums = index->keynums;
 	psdata.magma_idx.indkey = (int*)palloc0(idxCount * sizeof(int));
 	for (int i = 0; i < idxCount; ++i)
 	{
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index ab7593e..1302eca 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -2119,6 +2119,7 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
 										   InvalidOid,	/* not a relation constraint */
 										   NULL,
 										   0,
+										   0,
 										   domainOid,	/* domain constraint */
 										   InvalidOid,	/* Foreign key fields */
 										   NULL,
diff --git a/src/backend/executor/newExecutor.c b/src/backend/executor/newExecutor.c
index ed803bf..706dc8a 100644
--- a/src/backend/executor/newExecutor.c
+++ b/src/backend/executor/newExecutor.c
@@ -46,6 +46,13 @@ void checkOushuDbExtensiveFeatureSupport(char featureCategory[]) {
                         "HAWQ", featureCategory)));
 }
 
+void checkOushuDbExtensiveFunctionSupport(char functionString[]) {
+  if (MyExecutorRun == NULL)
+    ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR),
+                    errmsg("%s function is only supported in OushuDB "
+                        "Enterprise Edition", functionString)));
+}
+
 PlanState *newExecutorPlanStateReference = NULL;
 
 void exec_mpp_query_new(const char *plan, int len, int stageNo, bool setDisplay,
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index cd8664b..bf782ac 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2570,6 +2570,7 @@ _copyConstraint(Constraint *from)
 	COPY_NODE_FIELD(raw_expr);
 	COPY_STRING_FIELD(cooked_expr);
 	COPY_NODE_FIELD(keys);
+	COPY_NODE_FIELD(including);
 	COPY_NODE_FIELD(options);
 	COPY_STRING_FIELD(indexspace);
 
@@ -3339,6 +3340,7 @@ _copyIndexStmt(IndexStmt *from)
 	COPY_STRING_FIELD(accessMethod);
 	COPY_STRING_FIELD(tableSpace);
 	COPY_NODE_FIELD(indexParams);
+	COPY_NODE_FIELD(indexIncludingParams);
 	COPY_NODE_FIELD(options);
 	COPY_NODE_FIELD(whereClause);
 	COPY_NODE_FIELD(rangetable);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 7522a02..f04bb81 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1255,6 +1255,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
 	COMPARE_STRING_FIELD(accessMethod);
 	COMPARE_STRING_FIELD(tableSpace);
 	COMPARE_NODE_FIELD(indexParams);
+	COMPARE_NODE_FIELD(indexIncludingParams);
 	COMPARE_NODE_FIELD(options);
 	COMPARE_NODE_FIELD(whereClause);
 	COMPARE_NODE_FIELD(rangetable);
@@ -2147,6 +2148,7 @@ _equalConstraint(Constraint *a, Constraint *b)
 	COMPARE_NODE_FIELD(raw_expr);
 	COMPARE_STRING_FIELD(cooked_expr);
 	COMPARE_NODE_FIELD(keys);
+	COMPARE_NODE_FIELD(including);
 	COMPARE_NODE_FIELD(options);
 	COMPARE_STRING_FIELD(indexspace);
 
diff --git a/src/backend/nodes/outfast.c b/src/backend/nodes/outfast.c
index ddb08e8..51ed96a 100644
--- a/src/backend/nodes/outfast.c
+++ b/src/backend/nodes/outfast.c
@@ -1938,6 +1938,7 @@ _outIndexOptInfo(StringInfo str, IndexOptInfo *node)
 	WRITE_UINT_FIELD(pages);
 	WRITE_FLOAT_FIELD(tuples, "%.0f");
 	WRITE_INT_FIELD(ncolumns);
+	WRITE_INT_FIELD(nkeycolumns);
 
 	WRITE_INT_ARRAY(classlist, ncolumns, int);
 	WRITE_INT_ARRAY(indexkeys, ncolumns, int);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 4c2fdea..429e4e1 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2013,6 +2013,7 @@ _outIndexOptInfo(StringInfo str, IndexOptInfo *node)
 	WRITE_UINT_FIELD(pages);
 	WRITE_FLOAT_FIELD(tuples, "%.0f");
 	WRITE_INT_FIELD(ncolumns);
+	WRITE_INT_FIELD(nkeycolumns);
 
 	appendStringInfoLiteral(str, " :classlist");
 	for (i = 0; i < node->ncolumns; i++)
@@ -2262,6 +2263,7 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
 	WRITE_STRING_FIELD(accessMethod);
 	WRITE_STRING_FIELD(tableSpace);
 	WRITE_NODE_FIELD(indexParams);
+	WRITE_NODE_FIELD(indexIncludingParams);
 	WRITE_NODE_FIELD(options);
 
 	WRITE_NODE_FIELD(whereClause);
@@ -3854,6 +3856,7 @@ _outConstraint(StringInfo str, Constraint *node)
 		case CONSTR_PRIMARY:
 			appendStringInfoLiteral(str, "PRIMARY_KEY");
 			WRITE_NODE_FIELD(keys);
+			WRITE_NODE_FIELD(including);
 			WRITE_NODE_FIELD(options);
 			WRITE_STRING_FIELD(indexspace);
 			break;
@@ -3861,6 +3864,7 @@ _outConstraint(StringInfo str, Constraint *node)
 		case CONSTR_UNIQUE:
 			appendStringInfoLiteral(str, "UNIQUE");
 			WRITE_NODE_FIELD(keys);
+			WRITE_NODE_FIELD(including);
 			WRITE_NODE_FIELD(options);
 			WRITE_STRING_FIELD(indexspace);
 			break;
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 7fd2faa..24a22c7 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -2910,12 +2910,12 @@ expand_indexqual_rowcompare(RestrictInfo *rinfo,
 		 * insist the match be on the first such column, to avoid confusing
 		 * the executor.
 		 */
-		for (i = 0; i < index->ncolumns; i++)
+		for (i = 0; i < index->nkeycolumns; i++)
 		{
 			if (match_index_to_operand(varop, i, index))
 				break;
 		}
-		if (i >= index->ncolumns)
+		if (i >= index->nkeycolumns)
 			break;				/* no match found */
 
 		/* Now, do we have the right operator for this column? */
diff --git a/src/backend/optimizer/plan/newPlanner.c b/src/backend/optimizer/plan/newPlanner.c
index 7e7b852..4840f47 100644
--- a/src/backend/optimizer/plan/newPlanner.c
+++ b/src/backend/optimizer/plan/newPlanner.c
@@ -66,11 +66,11 @@ char *new_scheduler_mode;
 int new_interconnect_type;
 const char *show_new_interconnect_type() {
   switch (new_interconnect_type) {
-    case INTERCONNECT_TYPE_UDP:
-      return "UDP";
-    case INTERCONNECT_TYPE_TCP:
-    default:
-      return "TCP";
+  case INTERCONNECT_TYPE_UDP:
+    return "UDP";
+  case INTERCONNECT_TYPE_TCP:
+  default:
+    return "TCP";
   }
 }
 
@@ -95,8 +95,8 @@ static bool do_convert_initplan_to_common_plan(Plan *node,
 static bool do_convert_hashExpr_to_common_plan(Motion *node,
                                                CommonPlanContext *ctx);
 static void do_convert_onetbl_to_common_plan(Oid relid, CommonPlanContext *ctx);
-static void do_convert_magma_rangevseg_map_to_common_plan(
-    CommonPlanContext *ctx);
+static void
+do_convert_magma_rangevseg_map_to_common_plan(CommonPlanContext *ctx);
 static void do_convert_rangetbl_to_common_plan(List *rtable,
                                                CommonPlanContext *ctx);
 static void do_convert_token_map_to_common_plan(CommonPlanContext *ctx);
@@ -119,8 +119,9 @@ static bool do_convert_mergejoin_clause_to_common_plan(MergeJoin *node,
                                                        CommonPlanContext *ctx);
 static bool do_convert_result_qual_to_common_plan(Result *node,
                                                   CommonPlanContext *ctx);
-static bool do_convert_subqueryscan_subplan_to_common_plan(
-    SubqueryScan *node, CommonPlanContext *ctx);
+static bool
+do_convert_subqueryscan_subplan_to_common_plan(SubqueryScan *node,
+                                               CommonPlanContext *ctx);
 static Expr *parentExprSwitchTo(Expr *parent, CommonPlanContext *ctx);
 static void setDummyTListRef(CommonPlanContext *ctx);
 static void unsetDummyTListRef(CommonPlanContext *ctx);
@@ -136,49 +137,51 @@ static bool checkIsPrepareQuery(QueryDesc *queryDesc);
 #define INT64_MAX_LENGTH 20
 
 static bool checkSupportedTableFormat(Node *node, CommonPlanContext *cxt) {
-  if (NULL == node) return false;
+  if (NULL == node)
+    return false;
 
   switch (nodeTag(node)) {
-    case T_MagmaIndexScan:
-    case T_MagmaIndexOnlyScan:
-    case T_ExternalScan: {
-      ExternalScan *n = (ExternalScan *)node;
-      char fmtType = n->fmtType;
-      char *fmtName = NULL;
-      fmtName = getExtTblFormatterTypeInFmtOptsList(n->fmtOpts);
-
-      if (fmtType == 'b') {
-        if (!pg_strncasecmp(fmtName, ORCTYPE, sizeof(ORCTYPE) - 1)) {
-          cxt->querySelect = true;
-        }
-        if (!pg_strncasecmp(fmtName, MAGMATYPE, sizeof(MAGMATYPE) - 1)) {
-          cxt->querySelect = true;
-          cxt->isMagma = true;
-          cxt->magmaRelIndex = n->scan.scanrelid;
-        }
-      }
+  case T_MagmaIndexScan:
+  case T_MagmaIndexOnlyScan:
+  case T_ExternalScan: {
+    ExternalScan *n = (ExternalScan *)node;
+    char fmtType = n->fmtType;
+    char *fmtName = NULL;
+    fmtName = getExtTblFormatterTypeInFmtOptsList(n->fmtOpts);
 
-      if (fmtName) pfree(fmtName);
-      break;
-    }
-    case T_AppendOnlyScan: {
-      AppendOnlyScan *n = (AppendOnlyScan *)node;
-      RangeTblEntry *rte = rt_fetch(n->scan.scanrelid, cxt->stmt->rtable);
-      if (RELSTORAGE_ORC == get_rel_relstorage(rte->relid)) {
+    if (fmtType == 'b') {
+      if (!pg_strncasecmp(fmtName, ORCTYPE, sizeof(ORCTYPE) - 1)) {
         cxt->querySelect = true;
-        break;
-      } else {
-        cxt->convertible = false;
-        return true;
+      }
+      if (!pg_strncasecmp(fmtName, MAGMATYPE, sizeof(MAGMATYPE) - 1)) {
+        cxt->querySelect = true;
+        cxt->isMagma = true;
+        cxt->magmaRelIndex = n->scan.scanrelid;
       }
     }
 
-    case T_ParquetScan: {
+    if (fmtName)
+      pfree(fmtName);
+    break;
+  }
+  case T_AppendOnlyScan: {
+    AppendOnlyScan *n = (AppendOnlyScan *)node;
+    RangeTblEntry *rte = rt_fetch(n->scan.scanrelid, cxt->stmt->rtable);
+    if (RELSTORAGE_ORC == get_rel_relstorage(rte->relid)) {
+      cxt->querySelect = true;
+      break;
+    } else {
       cxt->convertible = false;
       return true;
     }
-    default:
-      break;
+  }
+
+  case T_ParquetScan: {
+    cxt->convertible = false;
+    return true;
+  }
+  default:
+    break;
   }
 
   return plan_tree_walker(node, checkSupportedTableFormat, cxt);
@@ -187,7 +190,8 @@ static bool checkSupportedTableFormat(Node *node, CommonPlanContext *cxt) {
 bool can_convert_common_plan(QueryDesc *queryDesc, CommonPlanContext *ctx) {
   PlannedStmt *stmt = queryDesc ? queryDesc->plannedstmt : NULL;
   // disable for cursor and bind message
-  if (!queryDesc || queryDesc->extended_query) return false;
+  if (!queryDesc || queryDesc->extended_query)
+    return false;
 
   // Disable new executor when too many TCP connection.
   // Here it considers only the TCP client number of the root plan, regardless
@@ -214,17 +218,20 @@ bool can_convert_common_plan(QueryDesc *queryDesc, CommonPlanContext *ctx) {
   planner_init_common_plan_context(stmt, ctx);
 
   // Fix issue 817
-  if (checkIsPrepareQuery(queryDesc)) goto end;
+  if (checkIsPrepareQuery(queryDesc))
+    goto end;
 
   stmt->planner_segments = queryDesc->planner_segments;
   stmt->originNodeType = queryDesc->originNodeType;
   convert_to_common_plan(stmt, ctx);
 
-  if (!ctx->convertible) goto end;
+  if (!ctx->convertible)
+    goto end;
 
   convert_querydesc_to_common_plan(queryDesc, ctx);
 
-  if (!ctx->convertible) goto end;
+  if (!ctx->convertible)
+    goto end;
 
   return true;
 
@@ -320,10 +327,12 @@ void convert_to_common_plan(PlannedStmt *stmt, CommonPlanContext *ctx) {
       do_convert_plantree_to_common_plan(subplan, -1, true, true, NIL, NULL,
                                          true, ctx);
   }
-  if (ctx->convertible) do_convert_rangetbl_to_common_plan(stmt->rtable, ctx);
+  if (ctx->convertible)
+    do_convert_rangetbl_to_common_plan(stmt->rtable, ctx);
   if (ctx->convertible && enable_secure_filesystem)
     do_convert_token_map_to_common_plan(ctx);
-  if (ctx->convertible && ctx->isMagma) do_convert_snapshot_to_common_plan(ctx);
+  if (ctx->convertible && ctx->isMagma)
+    do_convert_snapshot_to_common_plan(ctx);
 }
 
 void planner_init_common_plan_context(PlannedStmt *stmt,
@@ -359,20 +368,21 @@ void planner_destroy_common_plan_context(CommonPlanContext *ctx, bool enforce) {
 
 void get_all_stageno_from_plantree(Plan *node, int32_t *stageNo,
                                    int32_t *stageNum, bool *isInitPlan) {
-  if (node == NULL) return;
+  if (node == NULL)
+    return;
 
   switch (nodeTag(node)) {
-    case T_Motion: {
-      Motion *m = (Motion *)node;
-      stageNo[*stageNum] = m->motionID;
-      (*stageNum)++;
-      break;
-    }
-    case T_SubqueryScan: {
-      SubqueryScan *subqueryscan = (SubqueryScan *)node;
-      get_all_stageno_from_plantree(subqueryscan->subplan, stageNo, stageNum,
-                                    isInitPlan);
-    }
+  case T_Motion: {
+    Motion *m = (Motion *)node;
+    stageNo[*stageNum] = m->motionID;
+    (*stageNum)++;
+    break;
+  }
+  case T_SubqueryScan: {
+    SubqueryScan *subqueryscan = (SubqueryScan *)node;
+    get_all_stageno_from_plantree(subqueryscan->subplan, stageNo, stageNum,
+                                  isInitPlan);
+  }
   }
   if (node->initPlan) {
     ListCell *lc;
@@ -389,401 +399,478 @@ void do_convert_plantree_to_common_plan(Plan *node, int32_t pid, bool isLeft,
                                         bool isSubPlan, List *splits,
                                         Relation rel, bool insist,
                                         CommonPlanContext *ctx) {
-  if (node == NULL || !ctx->convertible) return;
+  if (node == NULL || !ctx->convertible)
+    return;
   int32_t uid;
 
   switch (nodeTag(node)) {
-    case T_Motion: {
-      Motion *m = (Motion *)node;
-      ConnectorType connType;
-      if (m->motionType == MOTIONTYPE_HASH) {
-        connType = UnivPlanShuffle;
-      } else if (m->motionType == MOTIONTYPE_FIXED) {
-        if (m->numOutputSegs == 0)
-          connType = UnivPlanBroadcast;
-        else
-          connType = UnivPlanConverge;
-      } else {
-        goto end;
-      }
-      uid = univPlanConnectorNewInstance(ctx->univplan, pid);
-      univPlanConnectorSetType(ctx->univplan, connType);
-      univPlanConnectorSetStageNo(ctx->univplan, m->motionID);
-      if (m->numSortCols > 0) {
-        int32_t *mappingSortFuncId = palloc(m->numSortCols * sizeof(int32_t));
-        int32_t *colIdx = palloc(m->numSortCols * sizeof(int32_t));
-        for (int i = 0; i < m->numSortCols; i++) {
-          mappingSortFuncId[i] =
-              HAWQ_FUNCOID_MAPPING(get_opcode(m->sortOperators[i]));
-          if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingSortFuncId[i])) goto end;
-          colIdx[i] = m->sortColIdx[i];
-        }
-        univPlanConnectorSetColIdx(ctx->univplan, m->numSortCols, colIdx);
-        univPlanConnectorSetSortFuncId(ctx->univplan, m->numSortCols,
-                                       mappingSortFuncId);
-        pfree(mappingSortFuncId);
-        pfree(colIdx);
-      }
-      if (m->plan.directDispatch.isDirectDispatch) {
-        List *contentIds = m->plan.directDispatch.contentIds;
-        Assert(list_length(contentIds) == 1);
-        univPlanConnectorSetDirectDispatchId(ctx->univplan,
-                                             linitial_int(contentIds));
-      }
-      if (connType == UnivPlanShuffle) {
-        if (!do_convert_hashExpr_to_common_plan(node, ctx)) goto end;
-      }
-      setDummyTListRef(ctx);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      unsetDummyTListRef(ctx);
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
+  case T_Motion: {
+    Motion *m = (Motion *)node;
+    ConnectorType connType;
+    if (m->motionType == MOTIONTYPE_HASH) {
+      connType = UnivPlanShuffle;
+    } else if (m->motionType == MOTIONTYPE_FIXED) {
+      if (m->numOutputSegs == 0)
+        connType = UnivPlanBroadcast;
+      else
+        connType = UnivPlanConverge;
+    } else {
+      goto end;
     }
-    case T_MagmaIndexScan:
-    case T_MagmaIndexOnlyScan:
-    case T_ExternalScan: {
-      ExternalScan *n = (ExternalScan *)node;
-      // currently we support orc and magma format
-      char fmtType = n->fmtType;
-      char *fmtName = NULL;
-      bool magmaTable = false;
-      fmtName = getExtTblFormatterTypeInFmtOptsList(n->fmtOpts);
-      // For orc and magma table have different infos in scan node
-      if (fmtName) {
-        if (!pg_strncasecmp(fmtName, MAGMATYPE, sizeof(MAGMATYPE) - 1)) {
-          magmaTable = true;
-        }
+    uid = univPlanConnectorNewInstance(ctx->univplan, pid);
+    univPlanConnectorSetType(ctx->univplan, connType);
+    univPlanConnectorSetStageNo(ctx->univplan, m->motionID);
+    if (m->numSortCols > 0) {
+      int32_t *mappingSortFuncId = palloc(m->numSortCols * sizeof(int32_t));
+      int32_t *colIdx = palloc(m->numSortCols * sizeof(int32_t));
+      for (int i = 0; i < m->numSortCols; i++) {
+        mappingSortFuncId[i] =
+            HAWQ_FUNCOID_MAPPING(get_opcode(m->sortOperators[i]));
+        if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingSortFuncId[i]))
+          goto end;
+        colIdx[i] = m->sortColIdx[i];
       }
-
-      if (fmtType != 'b' ||
-          (pg_strncasecmp(fmtName, ORCTYPE, sizeof(ORCTYPE) - 1) &&
-           pg_strncasecmp(fmtName, MAGMATYPE, sizeof(MAGMATYPE) - 1))) {
-        if (fmtName) pfree(fmtName);
+      univPlanConnectorSetColIdx(ctx->univplan, m->numSortCols, colIdx);
+      univPlanConnectorSetSortFuncId(ctx->univplan, m->numSortCols,
+                                     mappingSortFuncId);
+      pfree(mappingSortFuncId);
+      pfree(colIdx);
+    }
+    if (m->plan.directDispatch.isDirectDispatch) {
+      List *contentIds = m->plan.directDispatch.contentIds;
+      Assert(list_length(contentIds) == 1);
+      univPlanConnectorSetDirectDispatchId(ctx->univplan,
+                                           linitial_int(contentIds));
+    }
+    if (connType == UnivPlanShuffle) {
+      if (!do_convert_hashExpr_to_common_plan(node, ctx))
         goto end;
+    }
+    setDummyTListRef(ctx);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    unsetDummyTListRef(ctx);
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_MagmaIndexScan:
+  case T_MagmaIndexOnlyScan:
+  case T_ExternalScan: {
+    ExternalScan *n = (ExternalScan *)node;
+    // currently we support orc and magma format
+    char fmtType = n->fmtType;
+    char *fmtName = NULL;
+    bool magmaTable = false;
+    fmtName = getExtTblFormatterTypeInFmtOptsList(n->fmtOpts);
+    // For orc and magma table have different infos in scan node
+    if (fmtName) {
+      if (!pg_strncasecmp(fmtName, MAGMATYPE, sizeof(MAGMATYPE) - 1)) {
+        magmaTable = true;
       }
+    }
 
-      if (fmtName) pfree(fmtName);
+    if (fmtType != 'b' ||
+        (pg_strncasecmp(fmtName, ORCTYPE, sizeof(ORCTYPE) - 1) &&
+         pg_strncasecmp(fmtName, MAGMATYPE, sizeof(MAGMATYPE) - 1))) {
+      if (fmtName)
+        pfree(fmtName);
+      goto end;
+    }
 
-      ListCell *lc;
-      foreach (lc, n->uriList) {
-        char *url = (char *)strVal(lfirst(lc));
-        Uri *uri = ParseExternalTableUri(url);
-        if (uri == NULL ||
-            (uri->protocol != URI_HDFS && uri->protocol != URI_MAGMA)) {
-          goto end;
-        }
-      }
-      // calculate columns to read for seqscan
-      int32_t numColsToRead = 0;
-      Plan *plan = (Plan *)&((Scan *)node)->plan;
-      Oid relOid;
-      // scan magma table in old executor
-      if (magmaTable && rel != NULL) {
-        relOid = rel->rd_id;
-      } else {
-        // scan magma table in new executor
-        relOid = getrelid(((Scan *)node)->scanrelid, ctx->stmt->rtable);
-      }
-      int32_t numCols = get_relnatts(relOid);
-      bool *proj = (bool *)palloc0(sizeof(bool) * numCols);
-      GetNeededColumnsForScan((Node *)plan->targetlist, proj, numCols);
-      GetNeededColumnsForScan((Node *)plan->qual, proj, numCols);
-
-      //      if (magmaTable) {
-      //        int32_t i = 0;
-      //        for (; i < numCols; ++i) {
-      //          if (proj[i]) break;
-      //        }
-      //        if (i == numCols) proj[0] = true;
-      //      }
-
-      for (int32_t i = 0; i < numCols; i++) {
-        if (proj[i]) numColsToRead++;
-      }
+    if (fmtName)
+      pfree(fmtName);
 
-      int32_t *columnsToRead = palloc(numColsToRead * sizeof(int32_t));
-      int32_t index = 0;
-      for (int32_t i = 0; i < numCols; i++) {
-        if (proj[i]) columnsToRead[index++] = i + 1;
+    ListCell *lc;
+    foreach (lc, n->uriList) {
+      char *url = (char *)strVal(lfirst(lc));
+      Uri *uri = ParseExternalTableUri(url);
+      if (uri == NULL ||
+          (uri->protocol != URI_HDFS && uri->protocol != URI_MAGMA)) {
+        goto end;
       }
-      // This branch deal with magma table
-      if (magmaTable) {
-        uid = univPlanExtScanNewInstance(ctx->univplan, pid);
-        if (node->type != T_ExternalScan) {
-          univPlanExtScanSetIndex(ctx->univplan, true);
-          switch (node->type) {
-            case T_MagmaIndexScan:
-              univPlanExtScanSetScanType(ctx->univplan, ExternalIndexScan);
-              break;
-            case T_MagmaIndexOnlyScan:
-              univPlanExtScanSetScanType(ctx->univplan, ExternalIndexOnlyScan);
-              break;
-            default:
-              elog(ERROR, "unknown external scan type.");
-              break;
-          }
-          univPlanExtScanDirection(ctx->univplan,
-                                   ((ExternalScan *)node)->indexorderdir);
-          univPlanExtScanSetIndexName(ctx->univplan,
-                                      ((ExternalScan *)node)->indexname);
-          if (!do_convert_indexqual_to_common_plan(node, ctx, insist)) goto end;
-        } else {
-          univPlanExtScanSetScanType(ctx->univplan, NormalExternalScan);
-        }
-        univPlanExtScanSetRelId(ctx->univplan, ((Scan *)node)->scanrelid);
-        univPlanExtScanSetReadStatsOnly(ctx->univplan, ctx->scanReadStatsOnly);
-        if (columnsToRead)
-          univPlanExtScanSetColumnsToRead(ctx->univplan, numColsToRead,
-                                          columnsToRead);
-        // TODO(xsheng) cannot convert some TARGETENTRY to univplan because
-        // some expression types are not supported by universal plan.
-        // e.g. (composite type field)
-        //      update t_boxes set tp.len = (tp).len+1 where id = 2;
-        // currently we can support convert composite type(e.g. tp) but we
-        // cannot convert composite type field(e.g. tp.len)
-        // we won't use target list in the plan post-processing, comment it now
-        if (splits == NIL && ctx->stmt != NULL) {  // do it for new executor
-          if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-        }
-        // if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-        if (!do_convert_quallist_to_common_plan(node, ctx, insist)) goto end;
-        if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-        if (splits != NULL && ctx->stmt == NULL) {
-          // old executor, only convert magma external scan plan
-          do_convert_splits_list_to_common_plan(splits, relOid, ctx);
-        } else if (splits == NIL && ctx->stmt != NULL) {
-          // new executor, convert whole plan
-          do_convert_splits_to_common_plan((Scan *)node, relOid, ctx);
+    }
+    // calculate columns to read for seqscan
+    int32_t numColsToRead = 0;
+    Plan *plan = (Plan *)&((Scan *)node)->plan;
+    Oid relOid;
+    // scan magma table in old executor
+    if (magmaTable && rel != NULL) {
+      relOid = rel->rd_id;
+    } else {
+      // scan magma table in new executor
+      relOid = getrelid(((Scan *)node)->scanrelid, ctx->stmt->rtable);
+    }
+    int32_t numCols = get_relnatts(relOid);
+    bool *proj = (bool *)palloc0(sizeof(bool) * numCols);
+    GetNeededColumnsForScan((Node *)plan->targetlist, proj, numCols);
+    GetNeededColumnsForScan((Node *)plan->qual, proj, numCols);
+
+    //      if (magmaTable) {
+    //        int32_t i = 0;
+    //        for (; i < numCols; ++i) {
+    //          if (proj[i]) break;
+    //        }
+    //        if (i == numCols) proj[0] = true;
+    //      }
+
+    for (int32_t i = 0; i < numCols; i++) {
+      if (proj[i])
+        numColsToRead++;
+    }
+
+    int32_t *columnsToRead = palloc(numColsToRead * sizeof(int32_t));
+    int32_t index = 0;
+    for (int32_t i = 0; i < numCols; i++) {
+      if (proj[i])
+        columnsToRead[index++] = i + 1;
+    }
+    // This branch deal with magma table
+    if (magmaTable) {
+      uid = univPlanExtScanNewInstance(ctx->univplan, pid);
+      if (node->type != T_ExternalScan) {
+        univPlanExtScanSetIndex(ctx->univplan, true);
+        switch (node->type) {
+        case T_MagmaIndexScan:
+          univPlanExtScanSetScanType(ctx->univplan, ExternalIndexScan);
+          break;
+        case T_MagmaIndexOnlyScan:
+          univPlanExtScanSetScanType(ctx->univplan, ExternalIndexOnlyScan);
+          break;
+        default:
+          elog(ERROR, "unknown external scan type.");
+          break;
         }
-      } else if (!magmaTable) {  // This branch deal with orc table
-        uid = univPlanSeqScanNewInstance(ctx->univplan, pid);
-        univPlanSeqScanSetRelId(ctx->univplan, ((Scan *)node)->scanrelid);
-        univPlanSeqScanSetReadStatsOnly(ctx->univplan, ctx->scanReadStatsOnly);
-        if (columnsToRead)
-          univPlanSeqScanSetColumnsToRead(ctx->univplan, numColsToRead,
-                                          columnsToRead);
-        if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-        if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-        if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-        do_convert_splits_to_common_plan((Scan *)node, relOid, ctx);
+        univPlanExtScanDirection(ctx->univplan,
+                                 ((ExternalScan *)node)->indexorderdir);
+        univPlanExtScanSetIndexName(ctx->univplan,
+                                    ((ExternalScan *)node)->indexname);
+        if (!do_convert_indexqual_to_common_plan(node, ctx, insist))
+          goto end;
       } else {
-        goto end;
+        univPlanExtScanSetScanType(ctx->univplan, NormalExternalScan);
       }
-      break;
-    }
-    case T_AppendOnlyScan: {
-      int32_t numColsToRead = 0;
-      Plan *plan = (Plan *)&((Scan *)node)->plan;
-      Oid relOid = getrelid(((Scan *)node)->scanrelid, ctx->stmt->rtable);
-      int32_t numCols = get_relnatts(relOid);
-      bool *proj = (bool *)palloc0(sizeof(bool) * numCols);
-      GetNeededColumnsForScan((Node *)plan->targetlist, proj, numCols);
-      GetNeededColumnsForScan((Node *)plan->qual, proj, numCols);
-
-      for (int32_t i = 0; i < numCols; i++) {
-        if (proj[i]) numColsToRead++;
+      univPlanExtScanSetRelId(ctx->univplan, ((Scan *)node)->scanrelid);
+      univPlanExtScanSetReadStatsOnly(ctx->univplan, ctx->scanReadStatsOnly);
+      if (columnsToRead)
+        univPlanExtScanSetColumnsToRead(ctx->univplan, numColsToRead,
+                                        columnsToRead);
+      // TODO(xsheng) cannot convert some TARGETENTRY to univplan because
+      // some expression types are not supported by universal plan.
+      // e.g. (composite type field)
+      //      update t_boxes set tp.len = (tp).len+1 where id = 2;
+      // currently we can support convert composite type(e.g. tp) but we
+      // cannot convert composite type field(e.g. tp.len)
+      // we won't use target list in the plan post-processing, comment it now
+      if (splits == NIL && ctx->stmt != NULL) { // do it for new executor
+        if (!do_convert_targetlist_to_common_plan(node, ctx))
+          goto end;
       }
-
-      int32_t *columnsToRead = palloc(numColsToRead * sizeof(int32_t));
-      int32_t index = 0;
-      for (int32_t i = 0; i < numCols; i++) {
-        if (proj[i]) columnsToRead[index++] = i + 1;
+      // if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
+      if (!do_convert_quallist_to_common_plan(node, ctx, insist))
+        goto end;
+      if (!do_convert_initplan_to_common_plan(node, ctx))
+        goto end;
+      if (splits != NULL && ctx->stmt == NULL) {
+        // old executor, only convert magma external scan plan
+        do_convert_splits_list_to_common_plan(splits, relOid, ctx);
+      } else if (splits == NIL && ctx->stmt != NULL) {
+        // new executor, convert whole plan
+        do_convert_splits_to_common_plan((Scan *)node, relOid, ctx);
       }
+    } else if (!magmaTable) { // This branch deal with orc table
       uid = univPlanSeqScanNewInstance(ctx->univplan, pid);
       univPlanSeqScanSetRelId(ctx->univplan, ((Scan *)node)->scanrelid);
       univPlanSeqScanSetReadStatsOnly(ctx->univplan, ctx->scanReadStatsOnly);
       if (columnsToRead)
         univPlanSeqScanSetColumnsToRead(ctx->univplan, numColsToRead,
                                         columnsToRead);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      do_convert_splits_to_common_plan((Scan *)node, relOid, ctx);
-      break;
-    }
-    case T_Agg: {
-      Agg *agg = (Agg *)node;
-
-      uid = univPlanAggNewInstance(ctx->univplan, pid);
-      int64_t numCols = agg->numCols;
-      int32_t *grpColIdx = palloc(numCols * sizeof(int32_t));
-      for (int i = 0; i < numCols; ++i) grpColIdx[i] = agg->grpColIdx[i];
-      univPlanAggSetNumGroupsAndGroupColIndexes(ctx->univplan, agg->numGroups,
-                                                numCols, grpColIdx);
-      univPlanAggSetAggstrategy(ctx->univplan, agg->aggstrategy);
-      univPlanAggSetRollup(ctx->univplan, agg->numNullCols, agg->inputGrouping,
-                           agg->grouping, agg->rollupGSTimes,
-                           agg->inputHasGrouping, agg->lastAgg, agg->streaming);
-      pfree(grpColIdx);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      if (!isSubPlan) checkReadStatsOnlyForAgg(agg, ctx);
-      break;
-    }
-    case T_Sort: {
-      Sort *sort = (Sort *)node;
-      uid = univPlanSortNewInstance(ctx->univplan, pid);
-      int32_t *mappingSortFuncId = palloc(sort->numCols * sizeof(int32_t));
-      int32_t *colIdx = palloc(sort->numCols * sizeof(int32_t));
-      for (int i = 0; i < sort->numCols; i++) {
-        mappingSortFuncId[i] =
-            HAWQ_FUNCOID_MAPPING(get_opcode(sort->sortOperators[i]));
-        if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingSortFuncId[i])) goto end;
-        colIdx[i] = sort->sortColIdx[i];
-      }
-      univPlanSortSetColIdx(ctx->univplan, sort->numCols, colIdx);
-      univPlanSortSetSortFuncId(ctx->univplan, sort->numCols,
-                                mappingSortFuncId);
-      univPlanSortSetNoDuplicates(ctx->univplan, sort->noduplicates);
-      pfree(mappingSortFuncId);
-      pfree(colIdx);
-      if (!do_convert_sort_limit_to_common_plan(sort, ctx)) goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
-    }
-    case T_Limit: {
-      Limit *limit = (Limit *)node;
-      uid = univPlanLimitNewInstance(ctx->univplan, pid);
-      if (!do_convert_limit_to_common_plan(limit, ctx)) goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
-    }
-    case T_Append: {
-      Append *append = (Append *)node;
-      if (append->isTarget || append->plan.qual) goto end;
-      uid = univPlanAppendNewInstance(ctx->univplan, pid);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
-    }
-    case T_NestLoop: {
-      if (pg_strcasecmp(enable_alpha_newqe_str, "OFF") == 0) goto end;
-      NestLoop *nl = (NestLoop *)node;
-      if (nl->outernotreferencedbyinner || nl->shared_outer ||
-          nl->singleton_outer)
-        goto end;
-      uid = univPlanNestLoopNewInstance(ctx->univplan, pid);
-      if (!univPlanNestLoopSetType(ctx->univplan,
-                                   (UnivPlanCJoinType)nl->join.jointype))
-        goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_nestloop_joinqual_to_common_plan(nl, ctx)) goto end;
-      break;
-    }
-    case T_HashJoin: {
-      if (pg_strcasecmp(enable_alpha_newqe_str, "OFF") == 0) goto end;
-      HashJoin *hj = (HashJoin *)node;
-      uid = univPlanHashJoinNewInstance(ctx->univplan, pid);
-      if (!univPlanHashJoinSetType(ctx->univplan,
-                                   (UnivPlanCJoinType)hj->join.jointype))
-        goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_hashjoin_clause_to_common_plan(hj, ctx)) goto end;
-      break;
-    }
-    case T_Hash: {
-      uid = univPlanHashNewInstance(ctx->univplan, pid);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
-    }
-    case T_MergeJoin: {
-      MergeJoin *mj = (MergeJoin *)node;
-      uid = univPlanMergeJoinNewInstance(ctx->univplan, pid);
-      univPlanMergeJoinSetUniqueOuter(ctx->univplan, mj->unique_outer);
-      if (!univPlanMergeJoinSetType(ctx->univplan,
-                                    (UnivPlanCJoinType)mj->join.jointype))
+      if (!do_convert_targetlist_to_common_plan(node, ctx))
         goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_mergejoin_clause_to_common_plan(mj, ctx)) goto end;
-      break;
-    }
-    case T_Material: {
-      Material *material = (Material *)node;
-      uid = univPlanMaterialNewInstance(ctx->univplan, pid);
-      if (!univPlanMaterialSetAttr(
-              ctx->univplan, (UnivPlanCShareType)material->share_type,
-              material->cdb_strict, material->share_id, material->driver_slice,
-              material->nsharer, material->nsharer_xslice))
+      if (!do_convert_quallist_to_common_plan(node, ctx, true))
         goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
-    }
-    case T_ShareInputScan: {
-      ShareInputScan *shareInputScan = (ShareInputScan *)node;
-      uid = univPlanShareInputScanNewInstance(ctx->univplan, pid);
-      if (!univPlanShareInputScanSetAttr(
-              ctx->univplan, (UnivPlanCShareType)shareInputScan->share_type,
-              shareInputScan->share_id, shareInputScan->driver_slice))
+      if (!do_convert_initplan_to_common_plan(node, ctx))
         goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
-    }
-    case T_Result: {
-      Result *result = (Result *)node;
-      if (result->hashFilter) goto end;
-      uid = univPlanResultNewInstance(ctx->univplan, pid);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_result_qual_to_common_plan(result, ctx)) goto end;
-      break;
+      do_convert_splits_to_common_plan((Scan *)node, relOid, ctx);
+    } else {
+      goto end;
     }
-    case T_SubqueryScan: {
-      SubqueryScan *subqueryscan = (SubqueryScan *)node;
-      uid = univPlanSubqueryScanNewInstance(ctx->univplan, pid);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_subqueryscan_subplan_to_common_plan(subqueryscan, ctx))
-        goto end;
-      break;
+    break;
+  }
+  case T_AppendOnlyScan: {
+    int32_t numColsToRead = 0;
+    Plan *plan = (Plan *)&((Scan *)node)->plan;
+    Oid relOid = getrelid(((Scan *)node)->scanrelid, ctx->stmt->rtable);
+    int32_t numCols = get_relnatts(relOid);
+    bool *proj = (bool *)palloc0(sizeof(bool) * numCols);
+    GetNeededColumnsForScan((Node *)plan->targetlist, proj, numCols);
+    GetNeededColumnsForScan((Node *)plan->qual, proj, numCols);
+
+    for (int32_t i = 0; i < numCols; i++) {
+      if (proj[i])
+        numColsToRead++;
     }
-    case T_Unique: {
-      Unique *uniq = (Unique *)node;
-      uid = univPlanUniqueNewInstance(ctx->univplan, pid);
-      int64_t numCols = uniq->numCols;
-      int32_t *uniqColIdx = palloc(numCols * sizeof(int32_t));
-      for (int i = 0; i < numCols; ++i) uniqColIdx[i] = uniq->uniqColIdx[i];
-      univPlanUniqueSetNumGroupsAndUniqColIdxs(ctx->univplan, uniq->numCols,
-                                               uniqColIdx);
-      pfree(uniqColIdx);
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
+
+    int32_t *columnsToRead = palloc(numColsToRead * sizeof(int32_t));
+    int32_t index = 0;
+    for (int32_t i = 0; i < numCols; i++) {
+      if (proj[i])
+        columnsToRead[index++] = i + 1;
     }
-    case T_SetOp: {
-      SetOp *setop = (SetOp *)node;
-      uid = univPlanSetOpNewInstance(ctx->univplan, pid);
-      if (!univPlanSetOpSetAttr(ctx->univplan, setop->cmd, setop->numCols,
-                                setop->dupColIdx, setop->flagColIdx))
+    uid = univPlanSeqScanNewInstance(ctx->univplan, pid);
+    univPlanSeqScanSetRelId(ctx->univplan, ((Scan *)node)->scanrelid);
+    univPlanSeqScanSetReadStatsOnly(ctx->univplan, ctx->scanReadStatsOnly);
+    if (columnsToRead)
+      univPlanSeqScanSetColumnsToRead(ctx->univplan, numColsToRead,
+                                      columnsToRead);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    do_convert_splits_to_common_plan((Scan *)node, relOid, ctx);
+    break;
+  }
+  case T_Agg: {
+    Agg *agg = (Agg *)node;
+
+    uid = univPlanAggNewInstance(ctx->univplan, pid);
+    int64_t numCols = agg->numCols;
+    int32_t *grpColIdx = palloc(numCols * sizeof(int32_t));
+    for (int i = 0; i < numCols; ++i)
+      grpColIdx[i] = agg->grpColIdx[i];
+    univPlanAggSetNumGroupsAndGroupColIndexes(ctx->univplan, agg->numGroups,
+                                              numCols, grpColIdx);
+    univPlanAggSetAggstrategy(ctx->univplan, agg->aggstrategy);
+    univPlanAggSetRollup(ctx->univplan, agg->numNullCols, agg->inputGrouping,
+                         agg->grouping, agg->rollupGSTimes,
+                         agg->inputHasGrouping, agg->lastAgg, agg->streaming);
+    pfree(grpColIdx);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    if (!isSubPlan)
+      checkReadStatsOnlyForAgg(agg, ctx);
+    break;
+  }
+  case T_Sort: {
+    Sort *sort = (Sort *)node;
+    uid = univPlanSortNewInstance(ctx->univplan, pid);
+    int32_t *mappingSortFuncId = palloc(sort->numCols * sizeof(int32_t));
+    int32_t *colIdx = palloc(sort->numCols * sizeof(int32_t));
+    for (int i = 0; i < sort->numCols; i++) {
+      mappingSortFuncId[i] =
+          HAWQ_FUNCOID_MAPPING(get_opcode(sort->sortOperators[i]));
+      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingSortFuncId[i]))
         goto end;
-      if (!do_convert_targetlist_to_common_plan(node, ctx)) goto end;
-      if (!do_convert_quallist_to_common_plan(node, ctx, true)) goto end;
-      if (!do_convert_initplan_to_common_plan(node, ctx)) goto end;
-      break;
+      colIdx[i] = sort->sortColIdx[i];
     }
-    default:  // plannode not supported yet
+    univPlanSortSetColIdx(ctx->univplan, sort->numCols, colIdx);
+    univPlanSortSetSortFuncId(ctx->univplan, sort->numCols, mappingSortFuncId);
+    univPlanSortSetNoDuplicates(ctx->univplan, sort->noduplicates);
+    pfree(mappingSortFuncId);
+    pfree(colIdx);
+    if (!do_convert_sort_limit_to_common_plan(sort, ctx))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_Limit: {
+    Limit *limit = (Limit *)node;
+    uid = univPlanLimitNewInstance(ctx->univplan, pid);
+    if (!do_convert_limit_to_common_plan(limit, ctx))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_Append: {
+    Append *append = (Append *)node;
+    if (append->isTarget || append->plan.qual)
+      goto end;
+    uid = univPlanAppendNewInstance(ctx->univplan, pid);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_NestLoop: {
+    if (pg_strcasecmp(enable_alpha_newqe_str, "OFF") == 0)
+      goto end;
+    NestLoop *nl = (NestLoop *)node;
+    if (nl->outernotreferencedbyinner || nl->shared_outer ||
+        nl->singleton_outer)
+      goto end;
+    uid = univPlanNestLoopNewInstance(ctx->univplan, pid);
+    if (!univPlanNestLoopSetType(ctx->univplan,
+                                 (UnivPlanCJoinType)nl->join.jointype))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_nestloop_joinqual_to_common_plan(nl, ctx))
+      goto end;
+    break;
+  }
+  case T_HashJoin: {
+    if (pg_strcasecmp(enable_alpha_newqe_str, "OFF") == 0)
+      goto end;
+    HashJoin *hj = (HashJoin *)node;
+    uid = univPlanHashJoinNewInstance(ctx->univplan, pid);
+    if (!univPlanHashJoinSetType(ctx->univplan,
+                                 (UnivPlanCJoinType)hj->join.jointype))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_hashjoin_clause_to_common_plan(hj, ctx))
+      goto end;
+    break;
+  }
+  case T_Hash: {
+    uid = univPlanHashNewInstance(ctx->univplan, pid);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_MergeJoin: {
+    MergeJoin *mj = (MergeJoin *)node;
+    uid = univPlanMergeJoinNewInstance(ctx->univplan, pid);
+    univPlanMergeJoinSetUniqueOuter(ctx->univplan, mj->unique_outer);
+    if (!univPlanMergeJoinSetType(ctx->univplan,
+                                  (UnivPlanCJoinType)mj->join.jointype))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_mergejoin_clause_to_common_plan(mj, ctx))
+      goto end;
+    break;
+  }
+  case T_Material: {
+    Material *material = (Material *)node;
+    uid = univPlanMaterialNewInstance(ctx->univplan, pid);
+    if (!univPlanMaterialSetAttr(
+            ctx->univplan, (UnivPlanCShareType)material->share_type,
+            material->cdb_strict, material->share_id, material->driver_slice,
+            material->nsharer, material->nsharer_xslice))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_ShareInputScan: {
+    ShareInputScan *shareInputScan = (ShareInputScan *)node;
+    uid = univPlanShareInputScanNewInstance(ctx->univplan, pid);
+    if (!univPlanShareInputScanSetAttr(
+            ctx->univplan, (UnivPlanCShareType)shareInputScan->share_type,
+            shareInputScan->share_id, shareInputScan->driver_slice))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  case T_Result: {
+    Result *result = (Result *)node;
+    if (result->hashFilter)
+      goto end;
+    uid = univPlanResultNewInstance(ctx->univplan, pid);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_result_qual_to_common_plan(result, ctx))
+      goto end;
+    break;
+  }
+  case T_SubqueryScan: {
+    SubqueryScan *subqueryscan = (SubqueryScan *)node;
+    uid = univPlanSubqueryScanNewInstance(ctx->univplan, pid);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_subqueryscan_subplan_to_common_plan(subqueryscan, ctx))
+      goto end;
+    break;
+  }
+  case T_Unique: {
+    Unique *uniq = (Unique *)node;
+    uid = univPlanUniqueNewInstance(ctx->univplan, pid);
+    int64_t numCols = uniq->numCols;
+    int32_t *uniqColIdx = palloc(numCols * sizeof(int32_t));
+    for (int i = 0; i < numCols; ++i)
+      uniqColIdx[i] = uniq->uniqColIdx[i];
+    univPlanUniqueSetNumGroupsAndUniqColIdxs(ctx->univplan, uniq->numCols,
+                                             uniqColIdx);
+    pfree(uniqColIdx);
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
       goto end;
+    break;
+  }
+  case T_SetOp: {
+    SetOp *setop = (SetOp *)node;
+    uid = univPlanSetOpNewInstance(ctx->univplan, pid);
+    if (!univPlanSetOpSetAttr(ctx->univplan, setop->cmd, setop->numCols,
+                              setop->dupColIdx, setop->flagColIdx))
+      goto end;
+    if (!do_convert_targetlist_to_common_plan(node, ctx))
+      goto end;
+    if (!do_convert_quallist_to_common_plan(node, ctx, true))
+      goto end;
+    if (!do_convert_initplan_to_common_plan(node, ctx))
+      goto end;
+    break;
+  }
+  default: // plannode not supported yet
+    goto end;
   }
 
   univPlanSetPlanNodeInfo(ctx->univplan, node->plan_rows, node->plan_width,
@@ -816,7 +903,8 @@ bool do_convert_targetlist_to_common_plan(Plan *node, CommonPlanContext *ctx) {
   foreach (lc, node->targetlist) {
     TargetEntry *te = (TargetEntry *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, (Expr *)te, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, (Expr *)te, ctx))
+      return false;
     univPlanTargetListAddTargetEntry(ctx->univplan, te->resjunk);
   }
   return true;
@@ -869,7 +957,8 @@ bool do_convert_initplan_to_common_plan(Plan *node, CommonPlanContext *ctx) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
     bool convert_ret = do_convert_expr_to_common_plan(-1, expr, ctx);
-    if (!convert_ret) return false;
+    if (!convert_ret)
+      return false;
     univPlanInitplanAddExpr(ctx->univplan);
   }
   return true;
@@ -880,7 +969,8 @@ bool do_convert_hashExpr_to_common_plan(Motion *node, CommonPlanContext *ctx) {
   foreach (lc, node->hashExpr) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanConnectorAddHashExpr(ctx->univplan);
   }
   return true;
@@ -931,7 +1021,8 @@ bool do_convert_nestloop_joinqual_to_common_plan(NestLoop *node,
   foreach (lc, node->join.joinqual) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanNestLoopAddJoinQual(ctx->univplan);
   }
   return true;
@@ -944,21 +1035,24 @@ bool do_convert_hashjoin_clause_to_common_plan(HashJoin *node,
   foreach (lc, node->join.joinqual) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanHashJoinAddJoinQual(ctx->univplan);
   }
 
   foreach (lc, node->hashclauses) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanHashJoinAddHashClause(ctx->univplan);
   }
 
   foreach (lc, node->hashqualclauses) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanHashJoinAddHashQualClause(ctx->univplan);
   }
   return true;
@@ -970,13 +1064,15 @@ bool do_convert_mergejoin_clause_to_common_plan(MergeJoin *node,
   foreach (lc, node->join.joinqual) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanMergeJoinAddJoinQual(ctx->univplan);
   }
   foreach (lc, node->mergeclauses) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanMergeJoinAddMergeClause(ctx->univplan);
   }
   return true;
@@ -988,7 +1084,8 @@ bool do_convert_result_qual_to_common_plan(Result *node,
   foreach (lc, (List *)node->resconstantqual) {
     Expr *expr = (Expr *)lfirst(lc);
     univPlanNewExpr(ctx->univplan);
-    if (!do_convert_expr_to_common_plan(-1, expr, ctx)) return false;
+    if (!do_convert_expr_to_common_plan(-1, expr, ctx))
+      return false;
     univPlanResultAddResConstantQual(ctx->univplan);
   }
   return true;
@@ -1061,7 +1158,8 @@ void do_convert_splits_list_to_common_plan(List *splits, Oid relOid,
                                          logicEof, NULL, NULL);
 
     for (index = 0; index < fileSplitNum; ++index)
-      if (fileName[index]) pfree(fileName[index]);
+      if (fileName[index])
+        pfree(fileName[index]);
     pfree(fileName);
     pfree(start);
     pfree(len);
@@ -1298,9 +1396,12 @@ void do_convert_onetbl_to_common_plan(Oid relid, CommonPlanContext *ctx) {
                                   (const char **)columnName, columnDataType,
                                   columnDataTypeMod, targetName);
 
-    if (fmtOptsJson != NULL) pfree(fmtOptsJson);
-    if (fmtName != NULL) pfree(fmtName);
-    if (targetName != NULL) pfree(targetName);
+    if (fmtOptsJson != NULL)
+      pfree(fmtOptsJson);
+    if (fmtName != NULL)
+      pfree(fmtName);
+    if (targetName != NULL)
+      pfree(targetName);
     pfree(location);
   } else {
     univPlanRangeTblEntryAddDummy(ctx->univplan);
@@ -1375,410 +1476,432 @@ bool do_convert_expr_to_common_plan(int32_t pid, Expr *expr,
   ListCell *lc;
   Expr *old;
   switch (expr->type) {
-    case T_TargetEntry: {
-      TargetEntry *te = (TargetEntry *)expr;
-      old = parentExprSwitchTo(expr, ctx);
-      if (!do_convert_expr_to_common_plan(pid, te->expr, ctx)) goto end;
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+  case T_TargetEntry: {
+    TargetEntry *te = (TargetEntry *)expr;
+    old = parentExprSwitchTo(expr, ctx);
+    if (!do_convert_expr_to_common_plan(pid, te->expr, ctx))
+      goto end;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-    case T_RelabelType: {
-      RelabelType *te = (RelabelType *)expr;
-      old = parentExprSwitchTo(expr, ctx);
-      if (!do_convert_expr_to_common_plan(pid, te->arg, ctx)) goto end;
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+  case T_RelabelType: {
+    RelabelType *te = (RelabelType *)expr;
+    old = parentExprSwitchTo(expr, ctx);
+    if (!do_convert_expr_to_common_plan(pid, te->arg, ctx))
+      goto end;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-    case T_Var: {
-      Var *var = (Var *)expr;
-      // TODO(chiyang): support system attribute
-      if (var->varattno < 0 &&
-          !(var->varattno == SelfItemPointerAttributeNumber ||
-            var->varattno == GpSegmentIdAttributeNumber))
+  case T_Var: {
+    Var *var = (Var *)expr;
+    // TODO(chiyang): support system attribute
+    if (var->varattno < 0 &&
+        !(var->varattno == SelfItemPointerAttributeNumber ||
+          var->varattno == GpSegmentIdAttributeNumber))
+      goto end;
+    if (ctx->parent && ctx->parent->type == T_Aggref) {
+      Aggref *aggref = (Aggref *)ctx->parent;
+      univPlanAggrefAddProxyVar(ctx->univplan, pid, var->varattno,
+                                HAWQ_FUNCOID_MAPPING(aggref->aggfnoid),
+                                var->vartypmod, var->varnoold, var->varoattno);
+    } else {
+      Oid varType = var->vartype;
+      if (checkUnsupportedDataType(varType, DateStyle))
         goto end;
-      if (ctx->parent && ctx->parent->type == T_Aggref) {
-        Aggref *aggref = (Aggref *)ctx->parent;
-        univPlanAggrefAddProxyVar(ctx->univplan, pid, var->varattno,
-                                  HAWQ_FUNCOID_MAPPING(aggref->aggfnoid),
-                                  var->vartypmod, var->varnoold,
-                                  var->varoattno);
-      } else {
-        Oid varType = var->vartype;
-        if (checkUnsupportedDataType(varType, DateStyle)) goto end;
-        univPlanExprAddVar(
-            ctx->univplan, pid,
-            var->varno == DIRECT_LEFT_CHILD_VAR ? OUTER : var->varno,
-            var->varattno, map_hawq_type_to_common_plan(varType),
-            var->vartypmod, var->varnoold, var->varoattno);
-      }
-      break;
+      univPlanExprAddVar(ctx->univplan, pid,
+                         var->varno == DIRECT_LEFT_CHILD_VAR ? OUTER
+                                                             : var->varno,
+                         var->varattno, map_hawq_type_to_common_plan(varType),
+                         var->vartypmod, var->varnoold, var->varoattno);
     }
+    break;
+  }
 
-    case T_Const: {
-      Const *constval = (Const *)expr;
-      int32_t consttype = map_hawq_type_to_common_plan(constval->consttype);
-      if ((!constval->constisnull) &&
-          (checkUnsupportedDataType(constval->consttype, DateStyle)))
-        goto end;
-      if (ctx->setDummyTListRef && ctx->parent &&
-          ctx->parent->type == T_TargetEntry) {
-        univPlanExprAddVar(ctx->univplan, pid, OUTER,
-                           ((TargetEntry *)ctx->parent)->resno, consttype,
-                           constval->consttypmod, 0, 0);
-      } else {
-        Oid typoutput;
-        bool typIsVarlena;
-        getTypeOutputInfo(constval->consttype, &typoutput, &typIsVarlena);
-        char *extval = NULL;
-        if (!constval->constisnull) {
-          int savedDateStyle = DateStyle;
-          int savedDateOrder = DateOrder;
-          DateStyle = USE_ISO_DATES;
-          DateOrder = DATEORDER_MDY;
-          extval = OidOutputFunctionCall(typoutput, constval->constvalue);
-          DateStyle = savedDateStyle;
-          DateOrder = savedDateOrder;
-          if (constval->consttype == INTERVALOID) {
-            Interval *ival = (Interval *)DatumGetPointer(constval->constvalue);
-            extval = palloc(sizeof(char) * INT64_MAX_LENGTH * 2);
-            sprintf(extval, "%d:%d:%lld", ival->month, ival->day, ival->time);
-          }
+  case T_Const: {
+    Const *constval = (Const *)expr;
+    int32_t consttype = map_hawq_type_to_common_plan(constval->consttype);
+    if ((!constval->constisnull) &&
+        (checkUnsupportedDataType(constval->consttype, DateStyle)))
+      goto end;
+    if (ctx->setDummyTListRef && ctx->parent &&
+        ctx->parent->type == T_TargetEntry) {
+      univPlanExprAddVar(ctx->univplan, pid, OUTER,
+                         ((TargetEntry *)ctx->parent)->resno, consttype,
+                         constval->consttypmod, 0, 0);
+    } else {
+      Oid typoutput;
+      bool typIsVarlena;
+      getTypeOutputInfo(constval->consttype, &typoutput, &typIsVarlena);
+      char *extval = NULL;
+      if (!constval->constisnull) {
+        int savedDateStyle = DateStyle;
+        int savedDateOrder = DateOrder;
+        DateStyle = USE_ISO_DATES;
+        DateOrder = DATEORDER_MDY;
+        extval = OidOutputFunctionCall(typoutput, constval->constvalue);
+        DateStyle = savedDateStyle;
+        DateOrder = savedDateOrder;
+        if (constval->consttype == INTERVALOID) {
+          Interval *ival = (Interval *)DatumGetPointer(constval->constvalue);
+          extval = palloc(sizeof(char) * INT64_MAX_LENGTH * 2);
+          sprintf(extval, "%d:%d:%lld", ival->month, ival->day, ival->time);
         }
-        univPlanExprAddConst(ctx->univplan, pid, consttype,
-                             constval->constisnull, extval,
-                             constval->consttypmod);
       }
-      break;
+      univPlanExprAddConst(ctx->univplan, pid, consttype, constval->constisnull,
+                           extval, constval->consttypmod);
     }
+    break;
+  }
 
-    case T_OpExpr: {
-      OpExpr *opExpr = (OpExpr *)expr;
+  case T_OpExpr: {
+    OpExpr *opExpr = (OpExpr *)expr;
 
-      old = parentExprSwitchTo(expr, ctx);
+    old = parentExprSwitchTo(expr, ctx);
 
-      mappingFuncId = HAWQ_FUNCOID_MAPPING(opExpr->opfuncid);
-      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId)) goto end;
-      uid = univPlanExprAddOpExpr(ctx->univplan, pid, mappingFuncId);
-      foreach (lc, opExpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
-
-      parentExprSwitchTo(old, ctx);
-      break;
+    mappingFuncId = HAWQ_FUNCOID_MAPPING(opExpr->opfuncid);
+    if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId))
+      goto end;
+    uid = univPlanExprAddOpExpr(ctx->univplan, pid, mappingFuncId);
+    foreach (lc, opExpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
     }
 
-    case T_FuncExpr: {
-      FuncExpr *funcExpr = (FuncExpr *)expr;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      old = parentExprSwitchTo(expr, ctx);
+  case T_FuncExpr: {
+    FuncExpr *funcExpr = (FuncExpr *)expr;
 
-      mappingFuncId = HAWQ_FUNCOID_MAPPING(funcExpr->funcid);
-      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId)) goto end;
-      if (IS_HAWQ_MAPPING_DO_NOTHING(mappingFuncId)) {
-        if (funcExpr->args->length != 1) goto end;
-        foreach (lc, funcExpr->args) {
-          if (!do_convert_expr_to_common_plan(pid, lfirst(lc), ctx)) goto end;
-        }
-      } else {
-        uid = univPlanExprAddFuncExpr(ctx->univplan, pid, mappingFuncId);
-        foreach (lc, funcExpr->args) {
-          if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-        }
-      }
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
+    mappingFuncId = HAWQ_FUNCOID_MAPPING(funcExpr->funcid);
+    if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId))
+      goto end;
+    if (IS_HAWQ_MAPPING_DO_NOTHING(mappingFuncId)) {
+      if (funcExpr->args->length != 1)
+        goto end;
+      foreach (lc, funcExpr->args) {
+        if (!do_convert_expr_to_common_plan(pid, lfirst(lc), ctx))
+          goto end;
+      }
+    } else {
+      uid = univPlanExprAddFuncExpr(ctx->univplan, pid, mappingFuncId);
+      foreach (lc, funcExpr->args) {
+        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+          goto end;
+      }
     }
 
-    case T_Aggref: {
-      Aggref *aggref = (Aggref *)expr;
-
-      // disable count distinct case
-      if (aggref->aggdistinct || aggref->aggorder) goto end;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      old = parentExprSwitchTo(expr, ctx);
+  case T_Aggref: {
+    Aggref *aggref = (Aggref *)expr;
 
-      mappingFuncId = HAWQ_FUNCOID_MAPPING(aggref->aggfnoid);
-      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId)) goto end;
-      switch (aggref->aggstage) {
-        case AGGSTAGE_NORMAL:
-          uid = univPlanAggrefAddOneStage(ctx->univplan, pid, mappingFuncId);
-          break;
-        case AGGSTAGE_PARTIAL:
-          uid =
-              univPlanAggrefAddPartialStage(ctx->univplan, pid, mappingFuncId);
-          break;
-        case AGGSTAGE_INTERMEDIATE:
-          uid = univPlanAggrefAddIntermediateStage(ctx->univplan, pid,
-                                                   mappingFuncId);
-          break;
-        case AGGSTAGE_FINAL:
-          uid = univPlanAggrefAddFinalStage(ctx->univplan, pid, mappingFuncId);
-          break;
-        default:
-          goto end;
-      }
+    // disable count distinct case
+    if (aggref->aggdistinct || aggref->aggorder)
+      goto end;
 
-      foreach (lc, aggref->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
+    mappingFuncId = HAWQ_FUNCOID_MAPPING(aggref->aggfnoid);
+    if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId))
+      goto end;
+    switch (aggref->aggstage) {
+    case AGGSTAGE_NORMAL:
+      uid = univPlanAggrefAddOneStage(ctx->univplan, pid, mappingFuncId);
+      break;
+    case AGGSTAGE_PARTIAL:
+      uid = univPlanAggrefAddPartialStage(ctx->univplan, pid, mappingFuncId);
+      break;
+    case AGGSTAGE_INTERMEDIATE:
+      uid =
+          univPlanAggrefAddIntermediateStage(ctx->univplan, pid, mappingFuncId);
+      break;
+    case AGGSTAGE_FINAL:
+      uid = univPlanAggrefAddFinalStage(ctx->univplan, pid, mappingFuncId);
       break;
+    default:
+      goto end;
     }
-    case T_BoolExpr: {
-      BoolExpr *boolExpr = (BoolExpr *)expr;
 
-      old = parentExprSwitchTo(expr, ctx);
+    foreach (lc, aggref->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
+    }
 
-      uid = univPlanExprAddBoolExpr(ctx->univplan, pid,
-                                    (UnivplanBoolExprType)boolExpr->boolop);
-      foreach (lc, boolExpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
+  case T_BoolExpr: {
+    BoolExpr *boolExpr = (BoolExpr *)expr;
 
-      parentExprSwitchTo(old, ctx);
-      break;
+    old = parentExprSwitchTo(expr, ctx);
+
+    uid = univPlanExprAddBoolExpr(ctx->univplan, pid,
+                                  (UnivplanBoolExprType)boolExpr->boolop);
+    foreach (lc, boolExpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
     }
-    case T_NullTest: {
-      NullTest *nullTest = (NullTest *)expr;
 
-      old = parentExprSwitchTo(expr, ctx);
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
+  case T_NullTest: {
+    NullTest *nullTest = (NullTest *)expr;
 
-      uid = univPlanExprAddNullTestExpr(
-          ctx->univplan, pid, (UnivplanNullTestType)nullTest->nulltesttype);
-      if (!do_convert_expr_to_common_plan(uid, nullTest->arg, ctx)) goto end;
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
-    case T_BooleanTest: {
-      BooleanTest *boolTest = (BooleanTest *)expr;
+    uid = univPlanExprAddNullTestExpr(
+        ctx->univplan, pid, (UnivplanNullTestType)nullTest->nulltesttype);
+    if (!do_convert_expr_to_common_plan(uid, nullTest->arg, ctx))
+      goto end;
 
-      old = parentExprSwitchTo(expr, ctx);
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
+  case T_BooleanTest: {
+    BooleanTest *boolTest = (BooleanTest *)expr;
 
-      uid = univPlanExprAddBoolTestExpr(
-          ctx->univplan, pid, (UnivplanBooleanTestType)boolTest->booltesttype);
-      if (!do_convert_expr_to_common_plan(uid, boolTest->arg, ctx)) goto end;
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+    uid = univPlanExprAddBoolTestExpr(
+        ctx->univplan, pid, (UnivplanBooleanTestType)boolTest->booltesttype);
+    if (!do_convert_expr_to_common_plan(uid, boolTest->arg, ctx))
+      goto end;
 
-    case T_CaseExpr: {
-      CaseExpr *caseexpr = (CaseExpr *)expr;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      old = parentExprSwitchTo(expr, ctx);
+  case T_CaseExpr: {
+    CaseExpr *caseexpr = (CaseExpr *)expr;
 
-      ctx->exprBufStack = lcons(caseexpr->arg, ctx->exprBufStack);
+    old = parentExprSwitchTo(expr, ctx);
 
-      int32_t casetype = map_hawq_type_to_common_plan(caseexpr->casetype);
-      if (checkUnsupportedDataType(caseexpr->casetype, DateStyle)) {
-        goto end;
-      }
-      uid = univPlanExprAddCaseExpr(ctx->univplan, pid, casetype);
-      foreach (lc, caseexpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    ctx->exprBufStack = lcons(caseexpr->arg, ctx->exprBufStack);
 
-      univPlanExprAddCaseExprDefresult(ctx->univplan, uid);
-      if (!do_convert_expr_to_common_plan(uid, caseexpr->defresult, ctx))
+    int32_t casetype = map_hawq_type_to_common_plan(caseexpr->casetype);
+    if (checkUnsupportedDataType(caseexpr->casetype, DateStyle)) {
+      goto end;
+    }
+    uid = univPlanExprAddCaseExpr(ctx->univplan, pid, casetype);
+    foreach (lc, caseexpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
         goto end;
-
-      parentExprSwitchTo(old, ctx);
-      ctx->exprBufStack = list_delete_first(ctx->exprBufStack);
-      break;
     }
 
-    case T_CaseWhen: {
-      CaseWhen *casewhen = (CaseWhen *)expr;
+    univPlanExprAddCaseExprDefresult(ctx->univplan, uid);
+    if (!do_convert_expr_to_common_plan(uid, caseexpr->defresult, ctx))
+      goto end;
 
-      old = parentExprSwitchTo(expr, ctx);
+    parentExprSwitchTo(old, ctx);
+    ctx->exprBufStack = list_delete_first(ctx->exprBufStack);
+    break;
+  }
 
-      uid = univPlanExprAddCaseWhen(ctx->univplan, pid);
+  case T_CaseWhen: {
+    CaseWhen *casewhen = (CaseWhen *)expr;
 
-      univPlanExprAddCaseWhenExpr(ctx->univplan, uid);
-      if (!do_convert_expr_to_common_plan(uid, casewhen->expr, ctx)) goto end;
+    old = parentExprSwitchTo(expr, ctx);
 
-      univPlanExprAddCaseWhenResult(ctx->univplan, uid);
-      if (!do_convert_expr_to_common_plan(uid, casewhen->result, ctx)) goto end;
+    uid = univPlanExprAddCaseWhen(ctx->univplan, pid);
 
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+    univPlanExprAddCaseWhenExpr(ctx->univplan, uid);
+    if (!do_convert_expr_to_common_plan(uid, casewhen->expr, ctx))
+      goto end;
 
-    case T_CaseTestExpr: {
-      if (!do_convert_expr_to_common_plan(pid, linitial(ctx->exprBufStack),
-                                          ctx))
-        goto end;
-      break;
-    }
+    univPlanExprAddCaseWhenResult(ctx->univplan, uid);
+    if (!do_convert_expr_to_common_plan(uid, casewhen->result, ctx))
+      goto end;
 
-    case T_Param: {
-      Param *param = (Param *)expr;
-      if (param->paramkind != PARAM_EXEC) goto end;
-      univPlanExprAddParam(ctx->univplan, pid,
-                           (UnivplanParamKind)param->paramkind, param->paramid,
-                           map_hawq_type_to_common_plan(param->paramtype),
-                           param->paramtypmod);
-      break;
-    }
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-    case T_SubPlan: {
-      SubPlan *subplan = (SubPlan *)expr;
-      // TODO(chiyang): support ExecHashSubPlan
-      if (subplan->useHashTable) goto end;
-      if (!checkSupportedSubLinkType(subplan->subLinkType)) goto end;
-      uid = univPlanExprAddSubPlan(
-          ctx->univplan, pid, (UnivplanSubLinkType)subplan->subLinkType,
-          subplan->plan_id, subplan->qDispSliceId,
-          map_hawq_type_to_common_plan(subplan->firstColType),
-          subplan->firstColTypmod, subplan->useHashTable, subplan->is_initplan);
-      int num = 0;
-      if ((num = list_length(subplan->setParam)) > 0) {
-        int32_t *setParam = palloc(num * sizeof(int32_t));
-        int idx = 0;
-        foreach (lc, subplan->setParam)
-          setParam[idx++] = lfirst_int(lc);
-        univPlanSubPlanAddSetParam(ctx->univplan, uid, num, setParam);
-        pfree(setParam);
-      }
-      if ((num = list_length(subplan->parParam)) > 0) {
-        int32_t *parParam = palloc(num * sizeof(int32_t));
-        int idx = 0;
-        foreach (lc, subplan->parParam)
-          parParam[idx++] = lfirst_int(lc);
-        univPlanSubPlanAddParParam(ctx->univplan, uid, num, parParam);
-        pfree(parParam);
-      }
-      if ((num = list_length(subplan->paramIds)) > 0) {
-        int32_t *testexprParam = palloc(num * sizeof(int32_t));
-        int idx = 0;
-        foreach (lc, subplan->paramIds)
-          testexprParam[idx++] = lfirst_int(lc);
-        univPlanSubPlanAddTestexprParam(ctx->univplan, uid, num, testexprParam);
-        pfree(testexprParam);
-      }
-      foreach (lc, subplan->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
-      univPlanExprAddSubPlanTestexpr(ctx->univplan, uid);
-      if (subplan->testexpr &&
-          !do_convert_expr_to_common_plan(uid, (Expr *)subplan->testexpr, ctx))
+  case T_CaseTestExpr: {
+    if (!do_convert_expr_to_common_plan(pid, linitial(ctx->exprBufStack), ctx))
+      goto end;
+    break;
+  }
+
+  case T_Param: {
+    Param *param = (Param *)expr;
+    if (param->paramkind != PARAM_EXEC)
+      goto end;
+    univPlanExprAddParam(
+        ctx->univplan, pid, (UnivplanParamKind)param->paramkind, param->paramid,
+        map_hawq_type_to_common_plan(param->paramtype), param->paramtypmod);
+    break;
+  }
+
+  case T_SubPlan: {
+    SubPlan *subplan = (SubPlan *)expr;
+    // TODO(chiyang): support ExecHashSubPlan
+    if (subplan->useHashTable)
+      goto end;
+    if (!checkSupportedSubLinkType(subplan->subLinkType))
+      goto end;
+    uid = univPlanExprAddSubPlan(
+        ctx->univplan, pid, (UnivplanSubLinkType)subplan->subLinkType,
+        subplan->plan_id, subplan->qDispSliceId,
+        map_hawq_type_to_common_plan(subplan->firstColType),
+        subplan->firstColTypmod, subplan->useHashTable, subplan->is_initplan);
+    int num = 0;
+    if ((num = list_length(subplan->setParam)) > 0) {
+      int32_t *setParam = palloc(num * sizeof(int32_t));
+      int idx = 0;
+      foreach (lc, subplan->setParam)
+        setParam[idx++] = lfirst_int(lc);
+      univPlanSubPlanAddSetParam(ctx->univplan, uid, num, setParam);
+      pfree(setParam);
+    }
+    if ((num = list_length(subplan->parParam)) > 0) {
+      int32_t *parParam = palloc(num * sizeof(int32_t));
+      int idx = 0;
+      foreach (lc, subplan->parParam)
+        parParam[idx++] = lfirst_int(lc);
+      univPlanSubPlanAddParParam(ctx->univplan, uid, num, parParam);
+      pfree(parParam);
+    }
+    if ((num = list_length(subplan->paramIds)) > 0) {
+      int32_t *testexprParam = palloc(num * sizeof(int32_t));
+      int idx = 0;
+      foreach (lc, subplan->paramIds)
+        testexprParam[idx++] = lfirst_int(lc);
+      univPlanSubPlanAddTestexprParam(ctx->univplan, uid, num, testexprParam);
+      pfree(testexprParam);
+    }
+    foreach (lc, subplan->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
         goto end;
-      break;
     }
+    univPlanExprAddSubPlanTestexpr(ctx->univplan, uid);
+    if (subplan->testexpr &&
+        !do_convert_expr_to_common_plan(uid, (Expr *)subplan->testexpr, ctx))
+      goto end;
+    break;
+  }
 
-    case T_ScalarArrayOpExpr: {
-      ScalarArrayOpExpr *scalarArrayOpExpr = (ScalarArrayOpExpr *)expr;
-
-      old = parentExprSwitchTo(expr, ctx);
+  case T_ScalarArrayOpExpr: {
+    ScalarArrayOpExpr *scalarArrayOpExpr = (ScalarArrayOpExpr *)expr;
 
-      mappingFuncId = HAWQ_FUNCOID_MAPPING(scalarArrayOpExpr->opfuncid);
-      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId)) goto end;
-      uid = univPlanExprAddScalarArrayOpExpr(ctx->univplan, pid, mappingFuncId,
-                                             scalarArrayOpExpr->useOr);
-      foreach (lc, scalarArrayOpExpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
+    mappingFuncId = HAWQ_FUNCOID_MAPPING(scalarArrayOpExpr->opfuncid);
+    if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId))
+      goto end;
+    uid = univPlanExprAddScalarArrayOpExpr(ctx->univplan, pid, mappingFuncId,
+                                           scalarArrayOpExpr->useOr);
+    foreach (lc, scalarArrayOpExpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
     }
 
-    case T_CoalesceExpr: {
-      CoalesceExpr *coalesceExpr = (CoalesceExpr *)expr;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      old = parentExprSwitchTo(expr, ctx);
+  case T_CoalesceExpr: {
+    CoalesceExpr *coalesceExpr = (CoalesceExpr *)expr;
 
-      int32_t coalesceType =
-          map_hawq_type_to_common_plan(coalesceExpr->coalescetype);
-      if (checkUnsupportedDataType(coalesceExpr->coalescetype, DateStyle)) {
-        goto end;
-      }
-      uid = univPlanExprAddCoalesceExpr(ctx->univplan, pid, coalesceType,
-                                        exprTypmod(coalesceExpr));
-      foreach (lc, coalesceExpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
+    int32_t coalesceType =
+        map_hawq_type_to_common_plan(coalesceExpr->coalescetype);
+    if (checkUnsupportedDataType(coalesceExpr->coalescetype, DateStyle)) {
+      goto end;
+    }
+    uid = univPlanExprAddCoalesceExpr(ctx->univplan, pid, coalesceType,
+                                      exprTypmod(coalesceExpr));
+    foreach (lc, coalesceExpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
     }
 
-    case T_NullIfExpr: {
-      NullIfExpr *nullIfExpr = (NullIfExpr *)expr;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      old = parentExprSwitchTo(expr, ctx);
+  case T_NullIfExpr: {
+    NullIfExpr *nullIfExpr = (NullIfExpr *)expr;
 
-      mappingFuncId = HAWQ_FUNCOID_MAPPING(nullIfExpr->opfuncid);
-      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId)) goto end;
-      int32_t nullIfType = map_hawq_type_to_common_plan(exprType(nullIfExpr));
-      if (checkUnsupportedDataType(exprType(nullIfExpr), DateStyle)) {
-        goto end;
-      }
-      uid = univPlanExprAddNullIfExpr(ctx->univplan, pid, mappingFuncId,
-                                      nullIfType, exprTypmod(nullIfExpr));
-      foreach (lc, nullIfExpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
+    mappingFuncId = HAWQ_FUNCOID_MAPPING(nullIfExpr->opfuncid);
+    if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId))
+      goto end;
+    int32_t nullIfType = map_hawq_type_to_common_plan(exprType(nullIfExpr));
+    if (checkUnsupportedDataType(exprType(nullIfExpr), DateStyle)) {
+      goto end;
+    }
+    uid = univPlanExprAddNullIfExpr(ctx->univplan, pid, mappingFuncId,
+                                    nullIfType, exprTypmod(nullIfExpr));
+    foreach (lc, nullIfExpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
     }
 
-    case T_DistinctExpr: {
-      DistinctExpr *distExpr = (DistinctExpr *)expr;
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      old = parentExprSwitchTo(expr, ctx);
+  case T_DistinctExpr: {
+    DistinctExpr *distExpr = (DistinctExpr *)expr;
 
-      mappingFuncId = HAWQ_FUNCOID_MAPPING(distExpr->opfuncid);
-      if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId)) goto end;
-      uid = univPlanExprAddDistinctExpr(ctx->univplan, pid, mappingFuncId);
-      foreach (lc, distExpr->args) {
-        if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx)) goto end;
-      }
+    old = parentExprSwitchTo(expr, ctx);
 
-      parentExprSwitchTo(old, ctx);
-      break;
+    mappingFuncId = HAWQ_FUNCOID_MAPPING(distExpr->opfuncid);
+    if (IS_HAWQ_MAPPING_FUNCID_INVALID(mappingFuncId))
+      goto end;
+    uid = univPlanExprAddDistinctExpr(ctx->univplan, pid, mappingFuncId);
+    foreach (lc, distExpr->args) {
+      if (!do_convert_expr_to_common_plan(uid, lfirst(lc), ctx))
+        goto end;
     }
 
-    case T_Grouping: {
-      old = parentExprSwitchTo(expr, ctx);
-      uid = univPlanExprAddGrouping(ctx->univplan, pid);
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-    case T_GroupId: {
-      old = parentExprSwitchTo(expr, ctx);
-      uid = univPlanExprAddGroupId(ctx->univplan, pid);
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+  case T_Grouping: {
+    old = parentExprSwitchTo(expr, ctx);
+    uid = univPlanExprAddGrouping(ctx->univplan, pid);
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-    case T_GroupingFunc: {
-      GroupingFunc *groupingFunc = (GroupId *)expr;
-      old = parentExprSwitchTo(expr, ctx);
-      int32_t *args = palloc(list_length(groupingFunc->args) * sizeof(int32_t));
+  case T_GroupId: {
+    old = parentExprSwitchTo(expr, ctx);
+    uid = univPlanExprAddGroupId(ctx->univplan, pid);
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
 
-      ListCell *lc;
-      int idx = 0;
-      foreach (lc, groupingFunc->args) {
-        args[idx++] = (int)intVal(lfirst(lc));
-      }
-      uid = univPlanExprAddGroupingFunc(ctx->univplan, pid, args,
-                                        list_length(groupingFunc->args),
-                                        groupingFunc->ngrpcols);
-      pfree(args);
-      parentExprSwitchTo(old, ctx);
-      break;
-    }
+  case T_GroupingFunc: {
+    GroupingFunc *groupingFunc = (GroupId *)expr;
+    old = parentExprSwitchTo(expr, ctx);
+    int32_t *args = palloc(list_length(groupingFunc->args) * sizeof(int32_t));
 
-    default:
-      goto end;
+    ListCell *lc;
+    int idx = 0;
+    foreach (lc, groupingFunc->args) { args[idx++] = (int)intVal(lfirst(lc)); }
+    uid = univPlanExprAddGroupingFunc(ctx->univplan, pid, args,
+                                      list_length(groupingFunc->args),
+                                      groupingFunc->ngrpcols);
+    pfree(args);
+    parentExprSwitchTo(old, ctx);
+    break;
+  }
+
+  default:
+    goto end;
   }
 
   return true;
@@ -1822,10 +1945,12 @@ void checkUnsupportedStmt(PlannedStmt *stmt, CommonPlanContext *ctx) {
   if (stmt->commandType == CMD_INSERT && !checkInsertSupportTable(stmt))
     goto end;
 
-  if (stmt->originNodeType == T_CopyStmt) goto end;
+  if (stmt->originNodeType == T_CopyStmt)
+    goto end;
 
   // disable insert into for common plan currently
-  if (stmt->intoClause) goto end;
+  if (stmt->intoClause)
+    goto end;
 
   return;
 
@@ -1835,12 +1960,14 @@ end:
 
 bool checkInsertSupportTable(PlannedStmt *stmt) {
   // disable partitioned result target
-  if (stmt->result_partitions) return false;
-  if (list_length(stmt->resultRelations) > 1) return false;
+  if (stmt->result_partitions)
+    return false;
+  if (list_length(stmt->resultRelations) > 1)
+    return false;
   int32_t index = list_nth_int(stmt->resultRelations, 0);
   RangeTblEntry *rte = (RangeTblEntry *)list_nth(stmt->rtable, index - 1);
 
- // if (RELSTORAGE_ORC == get_rel_relstorage(rte->relid)) return true;
+  // if (RELSTORAGE_ORC == get_rel_relstorage(rte->relid)) return true;
 
   Relation pgExtTableRel = heap_open(ExtTableRelationId, RowExclusiveLock);
   cqContext cqc;
@@ -1849,13 +1976,15 @@ bool checkInsertSupportTable(PlannedStmt *stmt) {
                                       " WHERE reloid = :1 "
                                       " FOR UPDATE ",
                                       ObjectIdGetDatum(rte->relid)));
-  if (!HeapTupleIsValid(tuple)) goto end;
+  if (!HeapTupleIsValid(tuple))
+    goto end;
 
   bool isNull;
   char fmtCode =
       DatumGetChar(heap_getattr(tuple, Anum_pg_exttable_fmttype,
                                 RelationGetDescr(pgExtTableRel), &isNull));
-  if (!fmttype_is_custom(fmtCode)) goto end;
+  if (!fmttype_is_custom(fmtCode))
+    goto end;
 
   Datum fmtOptDatum = heap_getattr(tuple, Anum_pg_exttable_fmtopts,
                                    RelationGetDescr(pgExtTableRel), &isNull);
@@ -1868,7 +1997,8 @@ bool checkInsertSupportTable(PlannedStmt *stmt) {
   bool isSupported =
       fmtName && (!pg_strncasecmp(fmtName, "magmaap", FORMAT_MAGMAAP_LEN) ||
                   !pg_strncasecmp(fmtName, "orc", FORMAT_ORC_LEN));
-  if (!isSupported) goto end;
+  if (!isSupported)
+    goto end;
   heap_close(pgExtTableRel, RowExclusiveLock);
   return true;
 
@@ -1884,10 +2014,12 @@ void checkReadStatsOnlyForAgg(Agg *node, CommonPlanContext *ctx) {
       ((Plan *)node)->lefttree->type == T_Append ||
       ((Plan *)node)->lefttree->type == T_AppendOnlyScan) {
     // not work for group by statements
-    if (node->numCols - node->numNullCols > 0) return;
+    if (node->numCols - node->numNullCols > 0)
+      return;
 
     // not work for scan with filter
-    if (((Plan *)node)->lefttree->qual) return;
+    if (((Plan *)node)->lefttree->qual)
+      return;
 
     // for append node
     if (((Plan *)node)->lefttree->type == T_Append) {
@@ -1895,12 +2027,15 @@ void checkReadStatsOnlyForAgg(Agg *node, CommonPlanContext *ctx) {
       ListCell *lc;
       foreach (lc, appendNode->appendplans) {
         Plan *appendPlan = (Plan *)lfirst(lc);
-        if (!appendPlan->type == T_ExternalScan) return;
-        if (appendPlan->qual) return;
+        if (!appendPlan->type == T_ExternalScan)
+          return;
+        if (appendPlan->qual)
+          return;
         ListCell *lstcell;
         foreach (lstcell, appendPlan->targetlist) {
           TargetEntry *te = (TargetEntry *)lfirst(lstcell);
-          if (te->expr->type != T_Var) return;
+          if (te->expr->type != T_Var)
+            return;
         }
       }
     }
@@ -1920,7 +2055,8 @@ void checkReadStatsOnlyForAgg(Agg *node, CommonPlanContext *ctx) {
         return;
       }
       // special case for count(*)
-      if (list_length(aggref->args) == 0) return;
+      if (list_length(aggref->args) == 0)
+        return;
       ListCell *lc2;
       foreach (lc2, aggref->args) {
         Expr *expr = lfirst(lc2);
@@ -1952,14 +2088,14 @@ void checkReadStatsOnlyForAgg(Agg *node, CommonPlanContext *ctx) {
 
 bool checkSupportedSubLinkType(SubLinkType sublinkType) {
   switch (sublinkType) {
-    case EXISTS_SUBLINK:
-    case ALL_SUBLINK:
-    case ANY_SUBLINK:
-    case EXPR_SUBLINK:
-    case NOT_EXISTS_SUBLINK:
-      return true;
-    default:
-      return false;
+  case EXISTS_SUBLINK:
+  case ALL_SUBLINK:
+  case ANY_SUBLINK:
+  case EXPR_SUBLINK:
+  case NOT_EXISTS_SUBLINK:
+    return true;
+  default:
+    return false;
   }
 }
 
@@ -1991,33 +2127,33 @@ void convert_querydesc_to_common_plan(QueryDesc *queryDesc,
       char *extval = NULL;
       if (!pxd->isnull) {
         switch (pxd->ptype) {
-          case BOOLOID:
-          case INT8OID:
-          case INT4OID:
-          case INT2OID:
-          case FLOAT8OID:
-          case FLOAT4OID:
-          case TIMEOID:
-          case TIMETZOID:
-            extval = OidOutputFunctionCall(typoutput, pxd->value);
-            break;
-          case DATEOID:
-          case TIMESTAMPOID:
-          case TIMESTAMPTZOID:
-            DateStyle = USE_ISO_DATES;
-            DateOrder = DATEORDER_MDY;
+        case BOOLOID:
+        case INT8OID:
+        case INT4OID:
+        case INT2OID:
+        case FLOAT8OID:
+        case FLOAT4OID:
+        case TIMEOID:
+        case TIMETZOID:
+          extval = OidOutputFunctionCall(typoutput, pxd->value);
+          break;
+        case DATEOID:
+        case TIMESTAMPOID:
+        case TIMESTAMPTZOID:
+          DateStyle = USE_ISO_DATES;
+          DateOrder = DATEORDER_MDY;
+          extval = OidOutputFunctionCall(typoutput, pxd->value);
+          DateStyle = savedDateStyle;
+          DateOrder = savedDateOrder;
+          break;
+        case INTERVALOID: {
+          Interval *ival = (Interval *)DatumGetPointer(pxd->value);
+          extval = palloc(sizeof(char) * INT64_MAX_LENGTH * 2);
+          sprintf(extval, "%d-%d-%lld", ival->month, ival->day, ival->time);
+        } break;
+        default:
+          if (pxd->value)
             extval = OidOutputFunctionCall(typoutput, pxd->value);
-            DateStyle = savedDateStyle;
-            DateOrder = savedDateOrder;
-            break;
-          case INTERVALOID: {
-            Interval *ival = (Interval *)DatumGetPointer(pxd->value);
-            extval = palloc(sizeof(char) * INT64_MAX_LENGTH * 2);
-            sprintf(extval, "%d-%d-%lld", ival->month, ival->day, ival->time);
-          } break;
-          default:
-            if (pxd->value)
-              extval = OidOutputFunctionCall(typoutput, pxd->value);
         }
       }
       univPlanAddParamInfo(ctx->univplan,
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index 43a6a86..648100b 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -330,7 +330,7 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info)
 		 * designed index, there could be multiple matches, but we only care
 		 * about the first one.)
 		 */
-		for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
+		for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++)
 		{
 			indexscandir = match_agg_to_index_col(info, index, indexcol);
 			if (!ScanDirectionIsNoMovement(indexscandir))
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 6bcb76c..8935522 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -247,18 +247,20 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 			info->indexoid = index->indexrelid;
 			info->rel = rel;
 			info->ncolumns = ncolumns = index->indnatts;
+			info->nkeycolumns = index->indnkeyatts;
 
 			/*
 			 * Need to make classlist and ordering arrays large enough to put
 			 * a terminating 0 at the end of each one.
 			 */
 			info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
-			info->classlist = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1));
-			info->ordering = (Oid *) palloc0(sizeof(Oid) * (ncolumns + 1));
+			info->classlist = (Oid *) palloc0(sizeof(Oid) * (info->nkeycolumns + 1));
+			info->ordering = (Oid *) palloc0(sizeof(Oid) * (info->nkeycolumns + 1));
 
 			for (i = 0; i < ncolumns; i++)
 			{
-				info->classlist[i] = indexRelation->rd_indclass->values[i];
+			  if (i < info->nkeycolumns)
+			    info->classlist[i] = indexRelation->rd_indclass->values[i];
 				info->indexkeys[i] = index->indkey.values[i];
 			}
 
@@ -274,7 +276,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 			{
 				int			oprindex = amorderstrategy - 1;
 
-				for (i = 0; i < ncolumns; i++)
+				for (i = 0; i < info->nkeycolumns; i++)
 				{
 					info->ordering[i] = indexRelation->rd_operator[oprindex];
 					oprindex += indexRelation->rd_am->amstrategies;
@@ -1247,7 +1249,7 @@ has_unique_index(RelOptInfo *rel, AttrNumber attno)
 		 * unique.
 		 */
 		if (index->unique &&
-			index->ncolumns == 1 &&
+			index->nkeycolumns == 1 &&
 			index->indexkeys[0] == attno &&
 			index->indpred == NIL)
 			return true;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b15e069..4f50f65 100755
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -309,6 +309,7 @@ static Node *makeIsNotDistinctFromNode(Node *expr, int position);
 				opt_column_list columnList columnListPlus opt_name_list exttab_auth_list keyvalue_list
 				opt_inherited_column_list
 				sort_clause opt_sort_clause sortby_list index_params
+				opt_include opt_c_include index_including_params
 				name_list from_clause from_list opt_array_bounds
 				qualified_name_list any_name any_name_list
 				any_operator expr_list attrs
@@ -528,7 +529,7 @@ static Node *makeIsNotDistinctFromNode(Node *expr, int position);
 
 	HANDLER HASH HAVING HEADER_P HOLD HOST HOUR_P
 
-	IDENTITY_P IF_P  IGNORE_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING
+	IDENTITY_P IF_P  IGNORE_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDE INCLUDING
 	INCLUSIVE
 	INCREMENT
 	INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
@@ -3872,7 +3873,7 @@ ConstraintElem:
 					n->indexspace = NULL;
 					$$ = (Node *)n;
 				}
-			| UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
+			| UNIQUE '(' columnList ')' opt_c_include opt_definition OptConsTableSpace
 				{
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_UNIQUE;
@@ -3880,11 +3881,12 @@ ConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = $3;
-					n->options = $5;
-					n->indexspace = $6;
+					n->including = $5;
+					n->options = $6;
+					n->indexspace = $7;
 					$$ = (Node *)n;
 				}
-			| PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
+			| PRIMARY KEY '(' columnList ')' opt_c_include opt_definition OptConsTableSpace
 				{
 					Constraint *n = makeNode(Constraint);
 					n->contype = CONSTR_PRIMARY;
@@ -3892,8 +3894,9 @@ ConstraintElem:
 					n->raw_expr = NULL;
 					n->cooked_expr = NULL;
 					n->keys = $4;
-					n->options = $6;
-					n->indexspace = $7;
+					n->including = $6;
+					n->options = $7;
+					n->indexspace = $8;
 					$$ = (Node *)n;
 				}
 			| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name
@@ -3956,6 +3959,11 @@ columnElem: ColId
 				}
 		;
 
+opt_c_include:	INCLUDE '(' columnList ')'			{ $$ = $3; }
+			 |		/* EMPTY */						{ $$ = NIL; }
+		;
+
+
 key_match:  MATCH FULL
 			{
 				$$ = FKCONSTR_MATCH_FULL;
@@ -6962,7 +6970,7 @@ opt_granted_by: GRANTED BY RoleId						{ $$ = $3; }
 
 IndexStmt:	CREATE index_opt_unique INDEX index_name
 			ON qualified_name access_method_clause '(' index_params ')'
-			opt_definition OptTableSpace where_clause
+			opt_include opt_definition OptTableSpace where_clause
 				{
 					IndexStmt *n = makeNode(IndexStmt);
 					n->unique = $2;
@@ -6971,15 +6979,16 @@ IndexStmt:	CREATE index_opt_unique INDEX index_name
 					n->relation = $6;
 					n->accessMethod = $7;
 					n->indexParams = $9;
-					n->options = $11;
-					n->tableSpace = $12;
-					n->whereClause = $13;
+					n->indexIncludingParams = $11;
+					n->options = $12;
+					n->tableSpace = $13;
+					n->whereClause = $14;
 					n->idxOids = NULL;
 					$$ = (Node *)n;
 				}
 			| CREATE index_opt_unique INDEX CONCURRENTLY index_name
 			ON qualified_name access_method_clause '(' index_params ')'
-			opt_definition OptTableSpace where_clause
+			opt_include opt_definition OptTableSpace where_clause
 				{
 					IndexStmt *n = makeNode(IndexStmt);
 					n->unique = $2;
@@ -6988,9 +6997,10 @@ IndexStmt:	CREATE index_opt_unique INDEX index_name
 					n->relation = $7;
 					n->accessMethod = $8;
 					n->indexParams = $10;
-					n->options = $12;
-					n->tableSpace = $13;
-					n->whereClause = $14;
+					n->indexIncludingParams = $12;
+					n->options = $13;
+					n->tableSpace = $14;
+					n->whereClause = $15;
 
                     if (!gp_create_index_concurrently)
 					{
@@ -7048,6 +7058,15 @@ index_elem:	ColId opt_class
 				}
 		;
 
+opt_include:		INCLUDE '(' index_including_params ')'			{ $$ = $3; }
+			 |		/* EMPTY */						{ $$ = NIL; }
+		;
+
+index_including_params:	index_elem						{ $$ = list_make1($1); }
+			| index_including_params ',' index_elem		{ $$ = lappend($1, $3); }
+		;
+
+
 opt_class:	any_name								{ $$ = $1; }
 			| USING any_name						{ $$ = $2; }
 			| /*EMPTY*/								{ $$ = NIL; }
@@ -12867,6 +12886,7 @@ unreserved_keyword:
 			| IMMEDIATE
 			| IMMUTABLE
 			| IMPLICIT_P
+			| INCLUDE
 			| INCLUDING
 			| INCLUSIVE
 			| INCREMENT
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 75837aa..8c39e04 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -194,9 +194,10 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 
 	/* Build the list of IndexElem */
 	index->indexParams = NIL;
+	index->indexIncludingParams = NIL;
 
 	indexpr_item = list_head(indexprs);
-	for (keyno = 0; keyno < idxrec->indnatts; keyno++)
+	for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
 	{
 		IndexElem  *iparam;
 		AttrNumber	attnum = idxrec->indkey.values[keyno];
@@ -239,6 +240,33 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
 		index->indexParams = lappend(index->indexParams, iparam);
 	}
 
+	/* Handle included columns separately */
+	for (keyno = idxrec->indnkeyatts; keyno < idxrec->indnatts; keyno++)
+	{
+	  IndexElem  *iparam;
+	  AttrNumber  attnum = idxrec->indkey.values[keyno];
+
+	  iparam = makeNode(IndexElem);
+
+	  if (AttributeNumberIsValid(attnum))
+	  {
+	    /* Simple index column */
+	    char     *attname;
+
+	    attname = get_attname(indrelid, attnum);
+	    keycoltype = get_atttype(indrelid, attnum);
+
+	    iparam->name = attname;
+	    iparam->expr = NULL;
+	  }
+	  else
+	    ereport(ERROR,
+	            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+	                errmsg("expressions are not supported in included columns")));
+
+	  index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
+	}
+
 	/* Copy reloptions if any */
 	datum = caql_getattr(pcqCtx,
 						 Anum_pg_class_reloptions, &isnull);
@@ -315,6 +343,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 {
 	IndexStmt  *index;
 	ListCell   *keys;
+	ListCell   *lc;
 	IndexElem  *iparam;
 
 	index = makeNode(IndexStmt);
@@ -350,6 +379,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 	index->options = constraint->options;
 	index->tableSpace = constraint->indexspace;
 	index->indexParams = NIL;
+	index->indexIncludingParams = NIL;
 	index->whereClause = NULL;
 	index->concurrent = false;
 
@@ -475,6 +505,75 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 		index->indexParams = lappend(index->indexParams, iparam);
 	}
 
+	/* Add included columns to index definition */
+	foreach(lc, constraint->including)
+	{
+	  char     *key = strVal(lfirst(lc));
+	  bool    found = false;
+	  ColumnDef  *column = NULL;
+	  ListCell   *columns;
+	  IndexElem  *iparam;
+	  foreach(columns, cxt->columns)
+	  {
+	    column = (ColumnDef *) lfirst(columns);
+	    if (strcmp(column->colname, key) == 0)
+	    {
+	      found = true;
+	      break;
+	    }
+	    if (!found)
+	    {
+	      if (SystemAttributeByName(key, cxt->hasoids) != NULL)
+	      {
+	        found = true;
+	      }
+	      else if (cxt->inhRelations)
+	      {
+	        /* try inherited tables */
+	        ListCell   *inher;
+	        foreach(inher, cxt->inhRelations)
+	        {
+	          RangeVar   *inh = (RangeVar *) lfirst(inher);
+
+	          Relation  rel;
+	          int     count;
+
+	          rel = heap_openrv(inh, AccessShareLock);
+	          /* check user requested inheritance from valid relkind */
+	          if (rel->rd_rel->relkind != RELKIND_RELATION)
+	            ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+	                errmsg("inherited relation \"%s\" is not a table", inh->relname)));
+	          for (count = 0; count < rel->rd_att->natts; count++)
+	          {
+	            Form_pg_attribute inhattr = rel->rd_att->attrs[count];
+	            char     *inhname = NameStr(inhattr->attname);
+
+	            if (inhattr->attisdropped)
+	              continue;
+	            if (strcmp(key, inhname) == 0)
+	            {
+	              found = true;
+	            }
+	          }
+	          heap_close(rel, NoLock);
+	          if (found)
+	            break;
+	        }
+	      }
+	    }
+	  }
+	  if (!found && !cxt->isalter)
+	    ereport(ERROR,
+	            (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" named in key does not exist", key),
+	                errOmitLocation(true)));
+	  /* OK, add it to the index definition */
+	  iparam = makeNode(IndexElem);
+	  iparam->name = pstrdup(key);
+	  iparam->expr = NULL;
+	  iparam->opclass = NIL;
+	  index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
+	}
+
 	return index;
 }
 
@@ -772,6 +871,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt, bool mayDe
 			IndexStmt  *priorindex = lfirst(k);
 
 			if (equal(index->indexParams, priorindex->indexParams) &&
+			    equal(index->indexIncludingParams, priorindex->indexIncludingParams) &&
 				equal(index->whereClause, priorindex->whereClause) &&
 				strcmp(index->accessMethod, priorindex->accessMethod) == 0)
 			{
diff --git a/src/backend/utils/Gen_hawq_funcoid_mapping.sh b/src/backend/utils/Gen_hawq_funcoid_mapping.sh
index b81d04e..fb0ac37 100755
--- a/src/backend/utils/Gen_hawq_funcoid_mapping.sh
+++ b/src/backend/utils/Gen_hawq_funcoid_mapping.sh
@@ -482,19 +482,19 @@ BEGIN {
 		else if (oid == 668)
 			print "STRING_BPCHAR,";
 		else if (oid == 873)
-			printf "STRING_LPAD,";
+			print "STRING_LPAD,";
 		else if (oid == 874)
-			printf "STRING_RPAD,";
+			print "STRING_RPAD,";
 		else if (oid == 879)
-			printf "STRING_LPAD_NOFILL,";
+			print "STRING_LPAD_NOFILL,";
 		else if (oid == 880)
-			printf "STRING_RPAD_NOFILL,";
+			print "STRING_RPAD_NOFILL,";
 		else if (oid == 2557)
 			print "INT_TO_BOOLEAN,";
 		else if (oid == 2558)
 			print "BOOLEAN_TO_INT,";
 		else if (oid == 878)
-			printf "STRING_TRANSLATE,";
+			print "STRING_TRANSLATE,";
 		
 		else if (oid == 221 || oid == 1395)
 			print "DOUBLE_ABS,";
diff --git a/src/backend/utils/adt/array_distance_install.sql b/src/backend/utils/adt/array_distance_install.sql
index d17ea89..9925ea0 100644
--- a/src/backend/utils/adt/array_distance_install.sql
+++ b/src/backend/utils/adt/array_distance_install.sql
@@ -6,10 +6,19 @@
 --
 -- --------------------------------------------------------------------
 
-CREATE OR REPLACE FUNCTION pg_catalog.euclidean_metric_float4array(anyarray, anyarray) RETURNS float4 LANGUAGE internal IMMUTABLE AS 'euclidean_metric_float4array';
+-- euclidean_metric_float4array(float4array,float4array) =>,float 
+set gen_new_oid_value to 3135;
+insert into pg_proc values ('euclidean_metric_float4array',11,10,12,'f','f','f','f' ,'i',2,700,'f','1021 1021',null,null,null,'euclidean_metric_float4array','-',null,'n');
 
-CREATE OR REPLACE FUNCTION pg_catalog.euclidean_metric_float8array(anyarray, anyarray) RETURNS float8 LANGUAGE internal STABLE AS 'euclidean_metric_float8array';
+-- euclidean_metric_float8array(float8array,,'f'loat8array) => double
+set gen_new_oid_value to 3136;
+insert into pg_proc values ('euclidean_metric_float8array',11,10,12,'f','f','f','f' ,'i',2,701,'f','1022 1022',null,null,null,'euclidean_metric_float8array','-',null,'n');
 
-CREATE OR REPLACE FUNCTION pg_catalog.cosine_distance_float4array(anyarray, anyarray) RETURNS float8 LANGUAGE internal IMMUTABLE AS 'cosine_distance_float4array';
+-- cosine_distance_float4array(float4array,,'f'loat4array) => double
+set gen_new_oid_value to 3137;
+insert into pg_proc values ('cosine_distance_float4array',11,10,12,'f','f','f','f','i',2,701,'f','1021 1021',null,null,null,'cosine_distance_float4array','-',null,'n');
 
-CREATE OR REPLACE FUNCTION pg_catalog.cosine_distance_float8array(anyarray, anyarray) RETURNS float8 LANGUAGE internal IMMUTABLE AS 'cosine_distance_float8array';
+-- cosine_distance_float8array(float8array,,'f'loat8array) => double
+set gen_new_oid_value to 3138;
+insert into pg_proc values ('cosine_distance_float8array',11,10,12,'f','f','f','f','i',2,701,'f','1022 1022',null,null,null,'cosine_distance_float8array','-',null,'n');
+reset gen_new_oid_value;
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 6288326..e93a27d 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -756,6 +756,12 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, bool showTblSpc,
 	for (keyno = 0; keyno < idxrec->indnatts; keyno++)
 	{
 		AttrNumber	attnum = idxrec->indkey.values[keyno];
+		/* Report the INCLUDED attributes, if any. */
+		if (keyno == idxrec->indnkeyatts)
+		{
+		  appendStringInfoString(&buf, ") INCLUDE (");
+		  sep = "";
+		}
 
 		if (!colno)
 			appendStringInfoString(&buf, sep);
@@ -798,7 +804,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, bool showTblSpc,
 		/*
 		 * Add the operator class name
 		 */
-		if (!colno)
+		if (!colno && keyno < idxrec->indnkeyatts)
 			get_opclass_name(indclass->values[keyno], keycoltype,
 							 &buf);
 	}
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 12171fa..2aa4642 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -3884,7 +3884,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
 						 * should match has_unique_index().
 						 */
 						if (index->unique &&
-							index->ncolumns == 1 &&
+							index->nkeycolumns == 1 &&
 							index->indpred == NIL)
 							vardata->isunique = true;
 						/* Has it got stats? */
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 299d701..521d2b6 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -1365,7 +1365,8 @@ RelationInitIndexAccessInfo(Relation relation)
 	Oid		   *operator;
 	RegProcedure *support;
 	FmgrInfo   *supportinfo;
-	int			natts;
+	int     indnatts;
+	int     indnkeyatts;
 	uint16		amstrategies;
 	uint16		amsupport;
 
@@ -1412,10 +1413,11 @@ RelationInitIndexAccessInfo(Relation relation)
 	ReleaseSysCache(tuple);
 	relation->rd_am = aform;
 
-	natts = relation->rd_rel->relnatts;
-	if (natts != relation->rd_index->indnatts)
-		elog(ERROR, "relnatts disagrees with indnatts for index %u",
+	indnatts = RelationGetNumberOfAttributes(relation);
+	if (indnatts != IndexRelationGetNumberOfAttributes(relation))
+	  elog(ERROR, "relnatts disagrees with indnatts for index %u",
 			 RelationGetRelid(relation));
+	indnkeyatts = IndexRelationGetNumberOfKeyAttributes(relation);
 	amstrategies = aform->amstrategies;
 	amsupport = aform->amsupport;
 
@@ -1435,7 +1437,8 @@ RelationInitIndexAccessInfo(Relation relation)
 	relation->rd_indexcxt = indexcxt;
 
 	/*
-	 * Allocate arrays to hold data
+	 * Allocate arrays to hold data. Opclasses are not used for included
+	 * columns, so allocate them for indnkeyatts only.
 	 */
 	relation->rd_aminfo = (RelationAmInfo *)
 		MemoryContextAllocZero(indexcxt, sizeof(RelationAmInfo));
@@ -1443,13 +1446,13 @@ RelationInitIndexAccessInfo(Relation relation)
 	if (amstrategies > 0)
 		operator = (Oid *)
 			MemoryContextAllocZero(indexcxt,
-								   natts * amstrategies * sizeof(Oid));
+			                       indnkeyatts * amstrategies * sizeof(Oid));
 	else
 		operator = NULL;
 
 	if (amsupport > 0)
 	{
-		int			nsupport = natts * amsupport;
+		int			nsupport = indnkeyatts * amsupport;
 
 		support = (RegProcedure *)
 			MemoryContextAllocZero(indexcxt, nsupport * sizeof(RegProcedure));
@@ -1472,7 +1475,7 @@ RelationInitIndexAccessInfo(Relation relation)
 	 */
 	IndexSupportInitialize(relation->rd_indclass,
 						   operator, support,
-						   amstrategies, amsupport, natts);
+						   amstrategies, amsupport, indnkeyatts);
 
 	/*
 	 * expressions and predicate cache will be filled later
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 99bc381..6dbb897 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -7487,7 +7487,7 @@ static struct config_string ConfigureNamesString[] =
 			GUC_NOT_IN_SAMPLE
 		},
 		&new_executor_enable_external_sort_mode,
-		"OFF", assign_new_executor_mode, NULL
+		"AUTO", assign_new_executor_mode, NULL
 	},
 
 
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 7270f61..62749d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -827,7 +827,7 @@ tuplesort_begin_index(Relation indexRel,
 			 enforceUnique ? 't' : 'f',
 			 workMem, randomAccess ? 't' : 'f');
 
-	state->nKeys = RelationGetNumberOfAttributes(indexRel);
+	state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
 
 	state->comparetup = comparetup_index;
 	state->copytup = copytup_index;
diff --git a/src/backend/utils/sort/tuplesort_mk.c b/src/backend/utils/sort/tuplesort_mk.c
index e26c04f..ca32464 100644
--- a/src/backend/utils/sort/tuplesort_mk.c
+++ b/src/backend/utils/sort/tuplesort_mk.c
@@ -882,7 +882,7 @@ tuplesort_begin_index_mk(Relation indexRel,
     if (trace_sort)
         PG_TRACE3(tuplesort__begin, enforceUnique, workMem, randomAccess);
 
-    state->nKeys = RelationGetNumberOfAttributes(indexRel);
+    state->nKeys = IndexRelationGetNumberOfKeyAttributes(indexRel);
     tupdesc = RelationGetDescr(indexRel);
 
     state->copytup = copytup_index;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 73dd8b8..50991b8 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -3218,7 +3218,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 				i_oid,
 				i_indexname,
 				i_indexdef,
-				i_indnkeys,
+				i_indnnkeyatts,
+				i_indnatts,
 				i_indkey,
 				i_indisclustered,
 				i_contype,
@@ -3259,6 +3260,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 						  "SELECT t.tableoid, t.oid, "
 						  "t.relname as indexname, "
 					 "pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
+		                  "i.indnkeyatts AS indnkeyatts, "
+		                  "i.indnatts AS indnatts, "
 						  "t.relnatts as indnkeys, "
 						  "i.indkey, i.indisclustered, "
 						  "c.contype, c.conname, "
@@ -3288,7 +3291,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 		i_oid = PQfnumber(res, "oid");
 		i_indexname = PQfnumber(res, "indexname");
 		i_indexdef = PQfnumber(res, "indexdef");
-		i_indnkeys = PQfnumber(res, "indnkeys");
+		i_indnnkeyatts = PQfnumber(res, "indnkeyatts");
+		i_indnatts = PQfnumber(res, "indnatts");
 		i_indkey = PQfnumber(res, "indkey");
 		i_indisclustered = PQfnumber(res, "indisclustered");
 		i_contype = PQfnumber(res, "contype");
@@ -3313,7 +3317,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
 			indxinfo[j].dobj.namespace = tbinfo->dobj.namespace;
 			indxinfo[j].indextable = tbinfo;
 			indxinfo[j].indexdef = strdup(PQgetvalue(res, j, i_indexdef));
-			indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
+			indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnnkeyatts));
+			indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts));
 			indxinfo[j].tablespace = strdup(PQgetvalue(res, j, i_tablespace));
 			indxinfo[j].options = strdup(PQgetvalue(res, j, i_options));
 
@@ -8585,7 +8590,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 						  fmtId(coninfo->dobj.name),
 						  coninfo->contype == 'p' ? "PRIMARY KEY" : "UNIQUE");
 
-		for (k = 0; k < indxinfo->indnkeys; k++)
+		for (k = 0; k < indxinfo->indnkeyattrs; k++)
 		{
 			int			indkey = (int) indxinfo->indkeys[k];
 			const char *attname;
@@ -8598,6 +8603,22 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 							  (k == 0) ? "" : ", ",
 							  fmtId(attname));
 		}
+		if (indxinfo->indnkeyattrs < indxinfo->indnattrs)
+		  appendPQExpBuffer(q, ") INCLUDE (");
+
+		for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++)
+		{
+		  int     indkey = (int) indxinfo->indkeys[k];
+		  const char *attname;
+
+		  if (indkey == InvalidAttrNumber)
+		    break;
+		  attname = getAttrName(indkey, tbinfo);
+
+		  appendPQExpBuffer(q, "%s%s",
+		                    (k == indxinfo->indnkeyattrs) ? "" : ", ",
+		                        fmtId(attname));
+		}
 
 		appendPQExpBuffer(q, ")");
 
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 312f60e..54771c1 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -350,8 +350,10 @@ typedef struct _indxInfo
 	char	   *indexdef;
 	char	   *tablespace;		/* tablespace in which index is stored */
 	char	   *options;		/* options specified by WITH (...) */
-	int			indnkeys;
-	Oid		   *indkeys;
+	int      indnkeyattrs; /* number of index key attributes */
+	int      indnattrs;    /* total number of index attributes */
+	Oid      *indkeys;    /* In spite of the name 'indkeys' this field
+                 * contains both key and nonkey attributes */
 	bool		indisclustered;
 	/* if there is an associated constraint object, its dumpId: */
 	DumpId		indexconstraint;
diff --git a/src/include/access/orcam.h b/src/include/access/orcam.h
index a32fe5e..339ecba 100644
--- a/src/include/access/orcam.h
+++ b/src/include/access/orcam.h
@@ -33,14 +33,14 @@ typedef struct OrcInsertDescData {
   Relation rel;
   int32 segno;
   int64 insertCount;
-  OrcFormatData* orcFormatData;
+  OrcFormatData *orcFormatData;
   QueryContextDispatchingSendBack sendback;
   MemoryContext memCxt;
 } OrcInsertDescData;
 
 typedef struct OrcScanDescData {
   Relation rel;
-  OrcFormatData* orcFormatData;
+  OrcFormatData *orcFormatData;
   ItemPointerData cdb_fake_ctid;
 } OrcScanDescData;
 
@@ -48,7 +48,7 @@ typedef struct OrcDeleteDescData {
   Relation rel;
   int32 newSegno;
   Datum rowId;
-  OrcFormatData* orcFormatData;
+  OrcFormatData *orcFormatData;
   QueryContextDispatchingSendBack sendback;
   bool directDispatch;
 } OrcDeleteDescData;
@@ -58,51 +58,51 @@ typedef struct OrcUpdateDescData {
   int32 newSegno;
   int64 updateCount;
   Datum rowId;
-  TupleTableSlot* slot;
-  OrcFormatData* orcFormatData;
+  TupleTableSlot *slot;
+  OrcFormatData *orcFormatData;
   QueryContextDispatchingSendBack sendback;
   bool directDispatch;
   MemoryContext memCxt;
 } OrcUpdateDescData;
 
 // insert
-extern OrcInsertDescData* orcBeginInsert(Relation rel,
-                                         ResultRelSegFileInfo* segfileinfo);
-extern Oid orcInsert(OrcInsertDescData* insertDesc, TupleTableSlot* slot);
-extern Oid orcInsertValues(OrcInsertDescData* insertDesc, Datum* values,
-                           bool* nulls, TupleDesc tupleDesc);
-extern void orcEndInsert(OrcInsertDescData* insertDesc);
+extern OrcInsertDescData *orcBeginInsert(Relation rel,
+                                         ResultRelSegFileInfo *segfileinfo);
+extern Oid orcInsert(OrcInsertDescData *insertDesc, TupleTableSlot *slot);
+extern Oid orcInsertValues(OrcInsertDescData *insertDesc, Datum *values,
+                           bool *nulls, TupleDesc tupleDesc);
+extern void orcEndInsert(OrcInsertDescData *insertDesc);
 
 // scan
-extern void orcBeginScan(struct ScanState* scanState);
-extern TupleTableSlot* orcScanNext(struct ScanState* scanState);
-extern void orcEndScan(struct ScanState* scanState);
-extern void orcReScan(struct ScanState* scanState);
+extern void orcBeginScan(struct ScanState *scanState);
+extern TupleTableSlot *orcScanNext(struct ScanState *scanState);
+extern void orcEndScan(struct ScanState *scanState);
+extern void orcReScan(struct ScanState *scanState);
 
-extern OrcScanDescData* orcBeginRead(Relation rel, Snapshot snapshot,
-                                     TupleDesc desc, List* fileSplits,
-                                     bool* colToReads, void* pushDown);
-extern void orcReadNext(OrcScanDescData* scanData, TupleTableSlot* slot);
-extern void orcEndRead(OrcScanDescData* scanData);
-extern void orcResetRead(OrcScanDescData* scanData);
+extern OrcScanDescData *orcBeginRead(Relation rel, Snapshot snapshot,
+                                     TupleDesc desc, List *fileSplits,
+                                     bool *colToReads, void *pushDown);
+extern void orcReadNext(OrcScanDescData *scanData, TupleTableSlot *slot);
+extern void orcEndRead(OrcScanDescData *scanData);
+extern void orcResetRead(OrcScanDescData *scanData);
 
 // delete
-extern OrcDeleteDescData* orcBeginDelete(Relation rel, List* fileSplits,
-                                         List* relFileNodeInfo,
+extern OrcDeleteDescData *orcBeginDelete(Relation rel, List *fileSplits,
+                                         List *relFileNodeInfo,
                                          bool orderedRowId,
                                          bool directDispatch);
-extern void orcDelete(OrcDeleteDescData* deleteDesc);
-extern uint64 orcEndDelete(OrcDeleteDescData* deleteDesc);
+extern void orcDelete(OrcDeleteDescData *deleteDesc);
+extern uint64 orcEndDelete(OrcDeleteDescData *deleteDesc);
 
 // update
-extern OrcUpdateDescData* orcBeginUpdate(Relation rel, List* fileSplits,
-                                         List* relFileNodeInfo,
+extern OrcUpdateDescData *orcBeginUpdate(Relation rel, List *fileSplits,
+                                         List *relFileNodeInfo,
                                          bool orderedRowId,
                                          bool directDispatch);
-extern void orcUpdate(OrcUpdateDescData* updateDesc);
-extern uint64 orcEndUpdate(OrcUpdateDescData* updateDesc);
+extern void orcUpdate(OrcUpdateDescData *updateDesc);
+extern uint64 orcEndUpdate(OrcUpdateDescData *updateDesc);
 
 // utils
-extern bool isDirectDispatch(Plan* plan);
+extern bool isDirectDispatch(Plan *plan);
 
 #endif /* ORCAM_H_ */
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 17e51c6..d32d6d1 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -28,9 +28,11 @@ struct EState;                  /* #include "nodes/execnodes.h" */
  *		entries for a particular index.  Used for both index_build and
  *		retail creation of index entries.
  *
- *		NumIndexAttrs		number of columns in this index
+ *    NumIndexAttrs   total number of columns in this index
+ *    NumIndexKeyAttrs  number of key columns in index
  *		KeyAttrNumbers		underlying-rel attribute numbers used as keys
- *							(zeroes indicate expressions)
+ *		          (zeroes indicate expressions). It also contains
+ *		          info about included columns.
  *		Expressions			expr trees for expression entries, or NIL if none
  *		ExpressionsState	exec state for expressions, or NIL if none
  *		Predicate			partial-index predicate, or NIL if none
@@ -44,7 +46,8 @@ struct EState;                  /* #include "nodes/execnodes.h" */
 typedef struct IndexInfo
 {
 	NodeTag		type;
-	int			ii_NumIndexAttrs;
+	int   ii_NumIndexAttrs;     /* total number of columns in index */
+	int   ii_NumIndexKeyAttrs;  /* number of key columns in index */
 	AttrNumber	ii_KeyAttrNumbers[INDEX_MAX_KEYS];
 	List	   *ii_Expressions; /* list of Expr */
 	List	   *ii_ExpressionsState;	/* list of ExprState */
@@ -81,6 +84,7 @@ typedef struct MagmaIndexInfo
 	char *indexName;
 	int2vector *indkey;  // index on these columns
 	char *indexType;  // index type, default is btree
+	int  keynums;  // number of key columns in index
 	bool unique;
 	bool primary;
 } MagmaIndexInfo;
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 60d0fd9..4175d39 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -529,14 +529,15 @@ DATA(insert ( 1259 gp_segment_id   23 0  4  -8 0 -1 -1 t p i t f f t 0));
 { 0, {"indexrelid"},		26, -1, 4, 1, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 0, {"indrelid"},			26, -1, 4, 2, 0, -1, -1, true, 'p', 'i', true, false, false, true, 0 }, \
 { 0, {"indnatts"},			21, -1, 2, 3, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
-{ 0, {"indisunique"},		16, -1, 1, 4, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 0, {"indisprimary"},		16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 0, {"indisclustered"},	16, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 0, {"indisvalid"},		16, -1, 1, 7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
-{ 0, {"indkey"},			22, -1, -1, 8, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
-{ 0, {"indclass"},			30, -1, -1, 9, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
-{ 0, {"indexprs"},			25, -1, -1, 10, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
-{ 0, {"indpred"},			25, -1, -1, 11, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
+{ 0, {"indnkeyatts"},   21, -1, 2, 4, 0, -1, -1, true, 'p', 's', true, false, false, true, 0 }, \
+{ 0, {"indisunique"},		16, -1, 1, 5, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 0, {"indisprimary"},		16, -1, 1, 6, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 0, {"indisclustered"},	16, -1, 1, 7, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 0, {"indisvalid"},		16, -1, 1, 8, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
+{ 0, {"indkey"},			22, -1, -1, 9, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
+{ 0, {"indclass"},			30, -1, -1, 10, 1, -1, -1, false, 'p', 'i', true, false, false, true, 0 }, \
+{ 0, {"indexprs"},			25, -1, -1, 11, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
+{ 0, {"indpred"},			25, -1, -1, 12, 0, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
 
 
 #endif   /* PG_ATTRIBUTE_H */
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index 5d18c94..ac27538 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -195,6 +195,7 @@ extern Oid CreateConstraintEntry(const char *constraintName,
 								 Oid relId,
 								 const int16 *constraintKey,
 								 int constraintNKeys,
+								 int constraintNTotalKeys,
 								 Oid domainId,
 								 Oid foreignRelId,
 								 const int16 *foreignKey,
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index 116237f..0c34678 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -61,6 +61,7 @@ CATALOG(pg_index,2610) BKI_WITHOUT_OIDS
 	Oid			indexrelid;		/* OID of the index */
 	Oid			indrelid;		/* OID of the relation it indexes */
 	int2		indnatts;		/* number of columns in index */
+	int2    indnkeyatts ;  /* number of key columns in index */
 	bool		indisunique;	/* is this a unique index? */
 	bool		indisprimary;	/* is this index for primary key? */
 	bool		indisclustered; /* is this the index last clustered by? */
@@ -87,17 +88,18 @@ typedef FormData_pg_index *Form_pg_index;
  *		compiler constants for pg_index
  * ----------------
  */
-#define Natts_pg_index					11
+#define Natts_pg_index					12
 #define Anum_pg_index_indexrelid		1
 #define Anum_pg_index_indrelid			2
 #define Anum_pg_index_indnatts			3
-#define Anum_pg_index_indisunique		4
-#define Anum_pg_index_indisprimary		5
-#define Anum_pg_index_indisclustered	6
-#define Anum_pg_index_indisvalid		7
-#define Anum_pg_index_indkey			8
-#define Anum_pg_index_indclass			9
-#define Anum_pg_index_indexprs			10
-#define Anum_pg_index_indpred			11
+#define Anum_pg_index_indnkeyatts   4
+#define Anum_pg_index_indisunique		5
+#define Anum_pg_index_indisprimary  6
+#define Anum_pg_index_indisclustered	7
+#define Anum_pg_index_indisvalid		8
+#define Anum_pg_index_indkey			9
+#define Anum_pg_index_indclass			10
+#define Anum_pg_index_indexprs			11
+#define Anum_pg_index_indpred			12
 
 #endif   /* PG_INDEX_H */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 52bcb08..7bafd4d 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1512,7 +1512,9 @@ typedef struct Constraint {
   char *name;        /* name, or NULL if unnamed */
   Node *raw_expr;    /* expr, as untransformed parse tree */
   char *cooked_expr; /* expr, as nodeToString representation */
-  List *keys;        /* String nodes naming referenced column(s) */
+  List *keys;        /* String nodes naming referenced key column(s) */
+  List *including;    /* String nodes naming referenced nonkey
+                           * column(s) */
   List *options;     /* options from WITH clause */
   char *indexspace;  /* index tablespace for PKEY/UNIQUE
                                               * constraints; NULL for default */
@@ -2141,6 +2143,8 @@ typedef struct IndexStmt {
   char *accessMethod; /* name of access method (eg. btree) */
   char *tableSpace;   /* tablespace, or NULL to use parent's */
   List *indexParams;  /* a list of IndexElem */
+  List *indexIncludingParams; /* additional columns to index: a list
+                                  * of IndexElem */
   List *options;      /* options from WITH clause */
   Node *whereClause;  /* qualification (partial-index predicate) */
   List *rangetable;   /* range table for qual and/or expressions,
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 24a34a5..e735141 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -530,7 +530,9 @@ typedef struct IndexOptInfo
 	/* index descriptor information */
 	int			ncolumns;		/* number of columns in index */
 	Oid		   *classlist;		/* OIDs of operator classes for columns */
-	int		   *indexkeys;		/* column numbers of index's keys, or 0 */
+	int     nkeycolumns;  /* number of key columns in index */
+	int      *indexkeys;    /* column numbers of index's attributes both
+                 * key and included columns, or 0 */
 	Oid		   *ordering;		/* OIDs of sort operators for each column */
 	Oid			relam;			/* OID of the access method (in pg_am) */
 
diff --git a/src/include/optimizer/newPlanner.h b/src/include/optimizer/newPlanner.h
index ee1b242..97bcdf6 100644
--- a/src/include/optimizer/newPlanner.h
+++ b/src/include/optimizer/newPlanner.h
@@ -61,15 +61,15 @@ typedef struct CommonPlanContext {
   UnivPlanC *univplan;
   bool convertible;
   bool enforceNewScheduler;
-  bool querySelect;  // flag of query statement
-  bool isMagma;  // flag to indicate whether there is a magma table in the plan
+  bool querySelect; // flag of query statement
+  bool isMagma; // flag to indicate whether there is a magma table in the plan
   int magmaRelIndex;
   PlannedStmt *stmt;
   bool setDummyTListRef;
   bool scanReadStatsOnly;
-  Expr *parent;        // used for T_Var, T_Const
-  List *exprBufStack;  // used for T_Case
-  int rangeNum;        // magma range num
+  Expr *parent;       // used for T_Var, T_Const
+  List *exprBufStack; // used for T_Case
+  int rangeNum;       // magma range num
 } CommonPlanContext;
 
 extern bool can_convert_common_plan(QueryDesc *queryDesc,
@@ -89,4 +89,4 @@ extern void planner_init_common_plan_context(PlannedStmt *stmt,
 extern void planner_destroy_common_plan_context(CommonPlanContext *ctx,
                                                 bool enforce);
 
-#endif  // SRC_INCLUDE_OPTIMIZER_NEWPLANNER_H_
+#endif // SRC_INCLUDE_OPTIMIZER_NEWPLANNER_H_
diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h
index ec6cecb..3ded28e 100644
--- a/src/include/parser/kwlist.h
+++ b/src/include/parser/kwlist.h
@@ -206,6 +206,7 @@ PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD)
 PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD)
 PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD)
 PG_KEYWORD("in", IN_P, RESERVED_KEYWORD)
+PG_KEYWORD("include", INCLUDE, UNRESERVED_KEYWORD)
 PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD)
 PG_KEYWORD("inclusive", INCLUSIVE, UNRESERVED_KEYWORD)    /* GPDB */
 PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD)
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index e68ab6b..369b704 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -689,4 +689,6 @@ bool enableOushuDbExtensiveFeatureSupport();
 /* Log ERROR when extensive feature has not been supported, otherwise do nothing */
 void checkOushuDbExtensiveFeatureSupport(char featureCategory[]);
 
+/* Log ERROR when extensive function has not been supported, otherwise do nothing */
+void checkOushuDbExtensiveFunctionSupport(char functionString[]);
 #endif   /* GUC_H */
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 6582872..2424bee 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -423,6 +423,20 @@ typedef struct TidycatOptions
 #define RelationGetNumberOfAttributes(relation) ((relation)->rd_rel->relnatts)
 
 /*
+ * IndexRelationGetNumberOfAttributes
+ *    Returns the number of attributes in an index.
+ */
+#define IndexRelationGetNumberOfAttributes(relation) \
+    ((relation)->rd_index->indnatts)
+
+/*
+ * IndexRelationGetNumberOfKeyAttributes
+ *    Returns the number of key attributes in an index.
+ */
+#define IndexRelationGetNumberOfKeyAttributes(relation) \
+    ((relation)->rd_index->indnkeyatts)
+
+/*
  * RelationGetDescr
  *		Returns tuple descriptor for a relation.
  */
diff --git a/tools/bin/upgrade.sh b/tools/bin/upgrade.sh
index 37acab3..8452d57 100755
--- a/tools/bin/upgrade.sh
+++ b/tools/bin/upgrade.sh
@@ -18,27 +18,19 @@
 #
 
 # parse parameters
-usage() { echo "Usage: $0 [-s <3.3.x.x|2.4.0.0|2.4.0.1>] [-t <4.0.0.0>] [-h]" ; exit 1; }
+usage() { echo "Usage: $0 [-s <3.3.x.x|3.4.x.x|2.4.0.0|2.4.0.1>] [-h]" ; exit 1; }
 
 delete_hcatalog=true;
-while getopts ":s:t:h" opt; do
+while getopts ":s:h" opt; do
     case "${opt}" in
         s)
             source_version=${OPTARG}
-            if [[ "$source_version" =~ 3\.3\.[0-9]\.[0-9] || "$source_version" == "2.4.0.0" || "$source_version" == "2.4.0.1" ]];then
+            if [[ "$source_version" =~ 3\.[34]\.[0-9]\.[0-9] || "$source_version" == "2.4.0.0" || "$source_version" == "2.4.0.1" ]];then
                 echo "Input source version is $source_version."
             else
                 usage
             fi
             ;;
-        t)
-            target_version=${OPTARG}
-            if [[ "$target_version" == "4.0.0.0" ]];then
-                echo "Target source version is $target_version"
-            else
-                usage
-            fi
-            ;;
         h)
             delete_hcatalog=false
             echo "Don't delete hcatalog."
@@ -51,7 +43,7 @@ done
 
 shift $((OPTIND-1))
 
-if [ -z "${source_version}" ] || [ -z "${target_version}" ]; then
+if [ -z "${source_version}" ]; then
     usage
 fi
 
@@ -61,6 +53,13 @@ else
     upgrade_total=false
 fi
 
+upgrade_magmaview_only=false
+if [[ $source_version =~  3\.4\.[0-9]\.[0-9] ]]; then
+    upgrade_magmaview_only=true
+else
+    upgrade_magmaview_only=false
+fi
+
 check_error() {
     if [[ $? -ne 0 ]];then
         echo "Failed to $1."
@@ -92,26 +91,19 @@ fi
 # check master version
 version_str=`hawq --version`
 check_error "get hawq version on master"
-version=`echo "$version_str"| awk -F '[ ]' '{print $3}'`
-if [[ "$version" != "$target_version" ]];then
-    echo "Hawq version:$version is not same with target version:$target_version in master"
-    exit 1;
-fi
+target_version=`echo "$version_str"| awk -F '[ ]' '{print $3}'`
 echo "Upgrade begin, you can find logs of each module in folder $HOME/hawqAdminLogs/upgrade"
 
 MASTER_HOST=`get_guc "hawq_master_address_host"`
 MASTER_PORT=`get_guc "hawq_master_address_port"`
 SEGMENT_PORT=`get_guc "hawq_segment_address_port"`
 MASTER_TEMP_DIR=`get_guc "hawq_master_temp_directory"`
-SEGMENT_TEMP_DIR=`get_guc "hawq_segment_temp_directory"`
 SEGMENT_HOSTS=`cat $GPHOME/etc/slaves`
 OPTIONS='-c gp_maintenance_conn=true'
 
 # check whether all tmp dir exsits
-ls $MASTER_TEMP_DIR $SEGMENT_TEMP_DIR
+ls $MASTER_TEMP_DIR
 check_error "check master and segment temp dir on master"
-gpssh -f $GPHOME/etc/slaves "ls $MASTER_TEMP_DIR $SEGMENT_TEMP_DIR"
-check_error "check master and segment temp dir on all segments"
 
 # check whether all segments replaced with new binary
 result=`gpssh -f $GPHOME/etc/slaves "source $GPHOME/greenplum_path.sh;hawq --version;"`
@@ -141,7 +133,6 @@ check_error "set allow_system_table_mods to all"
 
 hawq start cluster -a
 check_error "start cluster in upgrade mode"
-
 echo "Start hawq cluster in upgrade mode successfully."
 
 if $delete_hcatalog ; then
@@ -170,7 +161,7 @@ install_function_by_database(){
     check_error "install $2 in database $1 in master" $error_count
     echo "Install $2 in database $1 in master successfully."
 
-    if [[ $1 == "template1" ]];then
+    if [[ $1 == "template1" && $2 != "monitor_install" ]];then
         #segment节点函数注册
         gpssh -f $GPHOME/etc/slaves "source $GPHOME/greenplum_path.sh;PGOPTIONS='$OPTIONS' psql -a -p $SEGMENT_PORT -d $1 -f $GPHOME/share/postgresql/${2}.sql 2>&1" > $HOME/hawqAdminLogs/upgrade/${1}_${2}.out
         check_error "install $2 in database $1 in segment"
@@ -182,6 +173,22 @@ install_function_by_database(){
 }
 
 upgrade_catalog() {
+    if $upgrade_magmaview_only ; then
+        PGOPTIONS="$OPTIONS" psql -p $MASTER_PORT -d $1 -c "drop view pg_catalog.hawq_magma_status;
+        CREATE VIEW pg_catalog.hawq_magma_status AS
+        SELECT * FROM hawq_magma_status() AS s
+        (node text,
+         compactJobRunning text,
+         compactJob text,
+         compactActionJobRunning text,
+         compactActionJob text,
+         dirs text,
+         description text);
+        "
+        check_error "update hawq_magma_status view in database $1 in master"
+        echo "update hawq_magma_status view in database $1 in master"
+        return
+    fi
     # template1库更改元数据
     if $2 ; then
         # 1、增加hive权限认证列
@@ -225,7 +232,7 @@ upgrade_catalog() {
 
     # 8、magma函数注册
     install_function_by_database $1 "magma_install"
-    
+
     # 9、监控函数注册
     install_function_by_database $1 "monitor_install"
 }