From ff6bc004dc3fa48cb9c8185944b524bbe4ab6e3f Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@pgaddict.com>
Date: Tue, 23 Jun 2015 19:32:02 +0200
Subject: [PATCH 17/24] Add ColumnStoreMaterial node

Defines the plan and executor nodes.
---
 src/backend/nodes/copyfuncs.c | 19 +++++++++++++++++++
 src/backend/nodes/outfuncs.c  | 11 +++++++++++
 src/include/nodes/execnodes.h | 25 +++++++++++++++++++++++++
 src/include/nodes/nodes.h     |  2 ++
 src/include/nodes/plannodes.h | 31 +++++++++++++++++++++++++++++++
 5 files changed, 88 insertions(+)

diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 3aaf221..ae5b0d3 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -786,6 +786,22 @@ _copyMaterial(const Material *from)
 	return newnode;
 }
 
+/*
+ * _copyColumnStoreMaterial
+ */
+static ColumnStoreMaterial *
+_copyColumnStoreMaterial(const ColumnStoreMaterial *from)
+{
+	ColumnStoreMaterial   *newnode = makeNode(ColumnStoreMaterial);
+
+	/*
+	 * copy node superclass fields
+	 */
+	CopyPlanFields((const Plan *) from, (Plan *) newnode);
+
+	return newnode;
+}
+
 
 /*
  * _copySort
@@ -4316,6 +4332,9 @@ copyObject(const void *from)
 		case T_Material:
 			retval = _copyMaterial(from);
 			break;
+		case T_ColumnStoreMaterial:
+			retval = _copyColumnStoreMaterial(from);
+			break;
 		case T_Sort:
 			retval = _copySort(from);
 			break;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 235b4e3..92a14fe 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -751,6 +751,14 @@ _outMaterial(StringInfo str, const Material *node)
 }
 
 static void
+_outColumnStoreMaterial(StringInfo str, const ColumnStoreMaterial *node)
+{
+	WRITE_NODE_TYPE("COLUMNSTOREMATERIAL");
+
+	_outPlanInfo(str, (const Plan *) node);
+}
+
+static void
 _outSort(StringInfo str, const Sort *node)
 {
 	int			i;
@@ -3093,6 +3101,9 @@ _outNode(StringInfo str, const void *obj)
 			case T_Material:
 				_outMaterial(str, obj);
 				break;
+			case T_ColumnStoreMaterial:
+				_outColumnStoreMaterial(str, obj);
+				break;
 			case T_Sort:
 				_outSort(str, obj);
 				break;
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5816a37..c0a9862 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1801,6 +1801,31 @@ typedef struct MaterialState
 } MaterialState;
 
 /* ----------------
+ *	 ColumnStoreMaterialState information
+ *
+ *		materialize nodes are used to fill-in values from a column store
+ *		into an ordinary tuple
+ *
+ *		unlike the regular Materialize node it does not store the data
+ *		into a tuple store or so, it just fills-in the values and
+ *		streams the tuple out (it may perform some internal batching
+ *		to benefit from the columnar storage, but it's not required to
+ *		materialize the whole result set)
+ *
+ *		ss.ss_ScanTupleSlot refers to output of underlying plan.
+ * ----------------
+ */
+typedef struct ColumnStoreMaterialState
+{
+	ScanState	ss;				/* its first field is NodeTag */
+	int			eflags;			/* capability flags */
+
+	/* TODO This likely requires additional fields (info about the
+	 *      colstore (ColumnScanDesc?) etc. */
+
+} ColumnStoreMaterialState;
+
+/* ----------------
  *	 SortState information
  * ----------------
  */
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 97efd24..f04dbcf 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -83,6 +83,7 @@ typedef enum NodeTag
 	T_NestLoopParam,
 	T_PlanRowMark,
 	T_PlanInvalItem,
+	T_ColumnStoreMaterial,
 
 	/*
 	 * TAGS FOR PLAN STATE NODES (execnodes.h)
@@ -126,6 +127,7 @@ typedef enum NodeTag
 	T_SetOpState,
 	T_LockRowsState,
 	T_LimitState,
+	T_ColumnStoreMaterialState,
 
 	/*
 	 * TAGS FOR PRIMITIVE NODES (primnodes.h)
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 0654d02..5167492 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -659,6 +659,37 @@ typedef struct Material
 } Material;
 
 /* ----------------
+ *		column store materialization node
+ * ----------------
+ *
+ * Reads tuples from the plan, and materializes columns from the column store,
+ * i.e. fetches values from the column store (identified by cststoreid) and
+ * sets them in the tuples. This is a bit like a special kind of join, except
+ * that we're not joining the relations using regular columns but using logical
+ * or physical ROWIDs.
+ *
+ * We'll want some join planning features (e.g. if there are multiple
+ * colstores, then decide in what order they should be materialized),
+ * but a regular join would require heap-ification of the column store,
+ * and that's not something we want to happen.
+ *
+ * As we foresee the option to place a column into multiple colstores,
+ * we also need to specify what attributes to materialize at this point
+ * (and what to leave for the next materializations). That's what
+ * matColIdx is for.
+ *
+ * XXX We're using TID as a ROWID for now, but in the future we expect other
+ *     kinds of IDs.
+ */
+typedef struct ColumnStoreMaterial
+{
+	Plan		plan;
+	Index		rti;			/* range table index of column store */
+	Oid			colstoreid;		/* OID of column store to materialize */
+	AttrNumber *matColIdx;		/* which attributes to materialize */
+} ColumnStoreMaterial;
+
+/* ----------------
  *		sort node
  * ----------------
  */
-- 
2.1.4

