diff --git a/contrib/btree_gist/btree_date.c b/contrib/btree_gist/btree_date.c
index 68a4107dbf..1941459025 100644
--- a/contrib/btree_gist/btree_date.c
+++ b/contrib/btree_gist/btree_date.c
@@ -178,6 +178,21 @@ gbt_date_distance(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 	DateADT		query = PG_GETARG_DATEADT(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	switch (strategy)
+	{
+		case RTLessStrategyNumber:
+			query = DATEVAL_NOBEGIN;
+			break;
+
+		case RTGreaterStrategyNumber:
+			query = DATEVAL_NOEND;
+			break;
+		
+		default:
+			break;
+	}
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	dateKEY    *kkk = (dateKEY *) DatumGetPointer(entry->key);
diff --git a/contrib/btree_gist/btree_gist--1.6--1.7.sql b/contrib/btree_gist/btree_gist--1.6--1.7.sql
index 1085216501..e1cc256e01 100644
--- a/contrib/btree_gist/btree_gist--1.6--1.7.sql
+++ b/contrib/btree_gist/btree_gist--1.6--1.7.sql
@@ -75,3 +75,29 @@ AS
 	FUNCTION	7	gbt_bool_same (gbtreekey2, gbtreekey2, internal),
 	FUNCTION	9   gbt_bool_fetch (internal),
 	STORAGE		gbtreekey2;
+
+
+-- Add ORDER BY support for int2, int4, int8, date, ts, time
+ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD
+	OPERATOR	20	< (int2, int2) FOR ORDER BY pg_catalog.integer_ops,
+	OPERATOR	22	> (int2, int2) FOR ORDER BY pg_catalog.integer_ops;
+
+ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD
+	OPERATOR	20	< (int4, int4) FOR ORDER BY pg_catalog.integer_ops,
+	OPERATOR	22	> (int4, int4) FOR ORDER BY pg_catalog.integer_ops;
+
+ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD
+	OPERATOR	20	< (int8, int8) FOR ORDER BY pg_catalog.integer_ops,
+	OPERATOR	22	> (int8, int8) FOR ORDER BY pg_catalog.integer_ops;
+
+ALTER OPERATOR FAMILY gist_date_ops USING gist ADD
+	OPERATOR	20	< (date, date) FOR ORDER BY pg_catalog.integer_ops,
+	OPERATOR	22	> (date, date) FOR ORDER BY pg_catalog.integer_ops;
+
+ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD
+	OPERATOR	20	< (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops,
+	OPERATOR	22	> (timestamp, timestamp) FOR ORDER BY pg_catalog.interval_ops;
+
+ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD
+	OPERATOR	20	< (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops,
+	OPERATOR	22	> (timestamptz, timestamptz) FOR ORDER BY pg_catalog.interval_ops;
diff --git a/contrib/btree_gist/btree_int2.c b/contrib/btree_gist/btree_int2.c
index fdbf156586..760a83ca4d 100644
--- a/contrib/btree_gist/btree_int2.c
+++ b/contrib/btree_gist/btree_int2.c
@@ -160,6 +160,19 @@ gbt_int2_distance(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 	int16		query = PG_GETARG_INT16(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	switch (strategy)
+	{
+		case RTLessStrategyNumber:
+			query = PG_INT16_MIN;
+			break;
+		case RTGreaterStrategyNumber:
+			query = PG_INT16_MAX;
+			break;
+		default:
+			break;
+	}
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	int16KEY   *kkk = (int16KEY *) DatumGetPointer(entry->key);
diff --git a/contrib/btree_gist/btree_int4.c b/contrib/btree_gist/btree_int4.c
index 8915fb5d08..8f072e55c0 100644
--- a/contrib/btree_gist/btree_int4.c
+++ b/contrib/btree_gist/btree_int4.c
@@ -161,6 +161,19 @@ gbt_int4_distance(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 	int32		query = PG_GETARG_INT32(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	switch (strategy)
+	{
+		case RTLessStrategyNumber:
+			query = PG_INT32_MIN;
+			break;
+		case RTGreaterStrategyNumber:
+			query = PG_INT32_MAX;
+			break;
+		default:
+			break;
+	}
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	int32KEY   *kkk = (int32KEY *) DatumGetPointer(entry->key);
diff --git a/contrib/btree_gist/btree_int8.c b/contrib/btree_gist/btree_int8.c
index 7c63a5b6dc..ac2c35f059 100644
--- a/contrib/btree_gist/btree_int8.c
+++ b/contrib/btree_gist/btree_int8.c
@@ -161,6 +161,21 @@ gbt_int8_distance(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 	int64		query = PG_GETARG_INT64(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	switch (strategy)
+	{
+		case RTLessStrategyNumber:
+			query = PG_INT64_MIN;
+			break;
+
+		case RTGreaterStrategyNumber:
+			query = PG_INT64_MAX;
+			break;
+		
+		default:
+			break;
+	}
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	int64KEY   *kkk = (int64KEY *) DatumGetPointer(entry->key);
diff --git a/contrib/btree_gist/btree_time.c b/contrib/btree_gist/btree_time.c
index d89401c0f5..e06efc0ceb 100644
--- a/contrib/btree_gist/btree_time.c
+++ b/contrib/btree_gist/btree_time.c
@@ -225,6 +225,21 @@ gbt_time_distance(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 	TimeADT		query = PG_GETARG_TIMEADT(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	switch (strategy)
+	{
+		case RTLessStrategyNumber:
+			query = PG_INT64_MIN;
+			break;
+
+		case RTGreaterStrategyNumber:
+			query = PG_INT64_MAX;
+			break;
+
+		default:
+			break;
+	}
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	timeKEY    *kkk = (timeKEY *) DatumGetPointer(entry->key);
diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c
index 3f5ba91891..b2b019a35c 100644
--- a/contrib/btree_gist/btree_ts.c
+++ b/contrib/btree_gist/btree_ts.c
@@ -274,6 +274,21 @@ gbt_ts_distance(PG_FUNCTION_ARGS)
 {
 	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
 	Timestamp	query = PG_GETARG_TIMESTAMP(1);
+	StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+
+	switch (strategy)
+	{
+		case RTLessStrategyNumber:
+			query = TIMESTAMP_MINUS_INFINITY;
+			break;
+
+		case RTGreaterStrategyNumber:
+			query = TIMESTAMP_INFINITY;
+			break;
+
+		default:
+			break;
+	}
 
 	/* Oid		subtype = PG_GETARG_OID(3); */
 	tsKEY	   *kkk = (tsKEY *) DatumGetPointer(entry->key);
diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c
index 7cf8532bc9..9db905f36e 100644
--- a/src/backend/executor/nodeBitmapIndexscan.c
+++ b/src/backend/executor/nodeBitmapIndexscan.c
@@ -269,7 +269,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
 	ExecIndexBuildScanKeys((PlanState *) indexstate,
 						   indexstate->biss_RelationDesc,
 						   node->indexqual,
-						   false,
+						   NULL,
 						   &indexstate->biss_ScanKeys,
 						   &indexstate->biss_NumScanKeys,
 						   &indexstate->biss_RuntimeKeys,
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index f1db35665c..7ba350c3fa 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -563,7 +563,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
 	ExecIndexBuildScanKeys((PlanState *) indexstate,
 						   indexstate->ioss_RelationDesc,
 						   node->indexqual,
-						   false,
+						   NULL,
 						   &indexstate->ioss_ScanKeys,
 						   &indexstate->ioss_NumScanKeys,
 						   &indexstate->ioss_RuntimeKeys,
@@ -577,7 +577,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
 	ExecIndexBuildScanKeys((PlanState *) indexstate,
 						   indexstate->ioss_RelationDesc,
 						   node->indexorderby,
-						   true,
+						   node->indexorderbyops,
 						   &indexstate->ioss_OrderByKeys,
 						   &indexstate->ioss_NumOrderByKeys,
 						   &indexstate->ioss_RuntimeKeys,
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 14b9c00217..fb8057c446 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -968,7 +968,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
 	ExecIndexBuildScanKeys((PlanState *) indexstate,
 						   indexstate->iss_RelationDesc,
 						   node->indexqual,
-						   false,
+						   NULL,
 						   &indexstate->iss_ScanKeys,
 						   &indexstate->iss_NumScanKeys,
 						   &indexstate->iss_RuntimeKeys,
@@ -982,7 +982,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
 	ExecIndexBuildScanKeys((PlanState *) indexstate,
 						   indexstate->iss_RelationDesc,
 						   node->indexorderby,
-						   true,
+						   node->indexorderbyops,
 						   &indexstate->iss_OrderByKeys,
 						   &indexstate->iss_NumOrderByKeys,
 						   &indexstate->iss_RuntimeKeys,
@@ -1134,12 +1134,13 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
  */
 void
 ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
-					   List *quals, bool isorderby,
+					   List *quals, List* orderbyops,
 					   ScanKey *scanKeys, int *numScanKeys,
 					   IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
 					   IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
 {
 	ListCell   *qual_cell;
+	ListCell   *orderbyop_cell;
 	ScanKey		scan_keys;
 	IndexRuntimeKeyInfo *runtime_keys;
 	IndexArrayKeyInfo *array_keys;
@@ -1148,6 +1149,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
 	int			max_runtime_keys;
 	int			n_array_keys;
 	int			j;
+	bool		isorderby	= (orderbyops != NULL);
 
 	/* Allocate array for ScanKey structs: one per qual */
 	n_scan_keys = list_length(quals);
@@ -1168,12 +1170,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
 		palloc0(n_scan_keys * sizeof(IndexArrayKeyInfo));
 	n_array_keys = 0;
 
+	/*
+	 * Make sure forboth below works in all cases
+	 */
+	if (!isorderby)
+	{
+		orderbyops = quals;
+	}
 	/*
 	 * for each opclause in the given qual, convert the opclause into a single
 	 * scan key
 	 */
 	j = 0;
-	foreach(qual_cell, quals)
+	forboth(qual_cell, quals, orderbyop_cell, orderbyops)
 	{
 		Expr	   *clause = (Expr *) lfirst(qual_cell);
 		ScanKey		this_scan_key = &scan_keys[j++];
@@ -1596,8 +1605,30 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
 								   InvalidOid,	/* no reg proc for this */
 								   (Datum) 0);	/* constant */
 		}
+		else if (isorderby && IsA(clause, Var))
+		{
+			Var	*var	= (Var *) clause;
+			int	flags	= SK_ORDER_BY;
+			varattno	= var->varattno;
+			opfamily	= index->rd_opfamily[varattno - 1];
+			opno		= lfirst(orderbyop_cell);
+			
+			get_op_opfamily_properties(opno, opfamily, isorderby,
+									   &op_strategy,
+									   &op_lefttype,
+									   &op_righttype);
+
+			ScanKeyEntryInitialize(this_scan_key,
+								   flags,
+								   varattno,	/* attribute number to scan */
+								   op_strategy, /* op's strategy */
+								   InvalidOid,	/* strategy subtype */
+								   var->varcollid,	/* collation */
+								   get_opcode(opno),	/* reg proc to use */
+								   (Datum) 0);	/* constant */
+		}
 		else
-			elog(ERROR, "unsupported indexqual type: %d",
+			elog(ERROR, "nodeIndexscan unsupported indexqual type: %d",
 				 (int) nodeTag(clause));
 	}
 
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 03a5fbdc6d..0855f917ea 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -188,7 +188,8 @@ static void match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
 									List **orderby_clauses_p,
 									List **clause_columns_p);
 static Expr *match_clause_to_ordering_op(IndexOptInfo *index,
-										 int indexcol, Expr *clause, Oid pk_opfamily);
+										 int indexcol, Expr *clause,
+										 Oid pk_opfamily, int pk_strategy);
 static bool ec_member_matches_indexcol(PlannerInfo *root, RelOptInfo *rel,
 									   EquivalenceClass *ec, EquivalenceMember *em,
 									   void *arg);
@@ -3092,8 +3093,8 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
 
 
 		/* Pathkey must request default sort order for the target opfamily */
-		if (pathkey->pk_strategy != BTLessStrategyNumber ||
-			pathkey->pk_nulls_first)
+		/* Fixme !!! */
+		if (!(pathkey->pk_strategy == BTLessStrategyNumber && !pathkey->pk_nulls_first || pathkey->pk_strategy == BTGreaterStrategyNumber && pathkey->pk_nulls_first))
 			return;
 
 		/* If eclass is volatile, no hope of using an indexscan */
@@ -3132,7 +3133,8 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
 				expr = match_clause_to_ordering_op(index,
 												   indexcol,
 												   member->em_expr,
-												   pathkey->pk_opfamily);
+												   pathkey->pk_opfamily,
+												   pathkey->pk_strategy);
 				if (expr)
 				{
 					*orderby_clauses_p = lappend(*orderby_clauses_p, expr);
@@ -3184,7 +3186,8 @@ static Expr *
 match_clause_to_ordering_op(IndexOptInfo *index,
 							int indexcol,
 							Expr *clause,
-							Oid pk_opfamily)
+							Oid pk_opfamily,
+							int pk_strategy)
 {
 	Oid			opfamily;
 	Oid			idxcollation;
@@ -3200,6 +3203,46 @@ match_clause_to_ordering_op(IndexOptInfo *index,
 	opfamily = index->opfamily[indexcol];
 	idxcollation = index->indexcollations[indexcol];
 
+	/*
+	 * If clause is a Var and matches the index then
+	 * try to find an ordering operator
+	 * registered as ordering operator in index operator family
+	 */
+	if (clause && IsA(clause, Var) && match_index_to_operand(clause, indexcol, index))
+	{
+		Var	*var = (Var *) clause;
+		/*
+		 * Copied from createplan.c - find ordering operator
+		 * There is an opportunity for refactoring
+		 * to avoid double cache lookup here and in creatplan
+		 */
+		Oid sortop = get_opfamily_member(pk_opfamily,
+										 var->vartype,
+										 var->vartype,
+										 pk_strategy);
+		/*
+		 * This should not happen???
+		 * For now just return no-match
+		 * Alternative is to err
+		 */
+		if (sortop == InvalidOid)
+			return NULL;
+
+		/*
+		 * Make sure
+		 * 1) ordering operator is registered in pg_amop for index am
+		 * 2) sort family is the same as requested ordering op family (BTree)
+		 */
+		Oid sortfamily = get_op_opfamily_sortfamily(sortop, opfamily);
+		if (sortfamily == pk_opfamily)
+			return clause;
+
+		/*
+		 * No match
+		 */
+		return NULL;
+	}
+
 	/*
 	 * Clause must be a binary opclause.
 	 */
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 34ca6d4ac2..b364419d08 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -189,6 +189,7 @@ static IndexOnlyScan *make_indexonlyscan(List *qptlist, List *qpqual,
 										 Index scanrelid, Oid indexid,
 										 List *indexqual, List *recheckqual,
 										 List *indexorderby,
+										 List *indexorderbyops,
 										 List *indextlist,
 										 ScanDirection indexscandir);
 static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid,
@@ -3170,6 +3171,7 @@ create_indexscan_plan(PlannerInfo *root,
 												fixed_indexquals,
 												stripped_indexquals,
 												fixed_indexorderbys,
+												indexorderbyops,
 												indexinfo->indextlist,
 												best_path->indexscandir);
 	else
@@ -5114,6 +5116,10 @@ fix_indexqual_clause(PlannerInfo *root, IndexOptInfo *index, int indexcol,
 												 index,
 												 indexcol);
 	}
+	else if (IsA(clause, Var))
+	{
+		clause = fix_indexqual_operand(clause, index, indexcol);
+	}
 	else
 		elog(ERROR, "unsupported indexqual type: %d",
 			 (int) nodeTag(clause));
@@ -5551,6 +5557,7 @@ make_indexonlyscan(List *qptlist,
 				   List *indexqual,
 				   List *recheckqual,
 				   List *indexorderby,
+				   List *indexorderbyops,
 				   List *indextlist,
 				   ScanDirection indexscandir)
 {
@@ -5566,6 +5573,7 @@ make_indexonlyscan(List *qptlist,
 	node->indexqual = indexqual;
 	node->recheckqual = recheckqual;
 	node->indexorderby = indexorderby;
+	node->indexorderbyops = indexorderbyops;
 	node->indextlist = indextlist;
 	node->indexorderdir = indexscandir;
 
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index c4fcd0076e..2233a213c1 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -6414,6 +6414,10 @@ index_other_operands_eval_cost(PlannerInfo *root, List *indexquals)
 		{
 			other_operand = NULL;
 		}
+		else if (IsA(clause, Var))
+		{
+			other_operand = (Node *) clause;
+		}
 		else
 		{
 			elog(ERROR, "unsupported indexqual type: %d",
diff --git a/src/include/executor/nodeIndexscan.h b/src/include/executor/nodeIndexscan.h
index 8ee7969792..de6d77f1c3 100644
--- a/src/include/executor/nodeIndexscan.h
+++ b/src/include/executor/nodeIndexscan.h
@@ -34,7 +34,8 @@ extern void ExecIndexScanInitializeWorker(IndexScanState *node,
  * nodeBitmapIndexscan.c
  */
 extern void ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
-								   List *quals, bool isorderby,
+								   List *quals,
+								   List *orderbyops,
 								   ScanKey *scanKeys, int *numScanKeys,
 								   IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
 								   IndexArrayKeyInfo **arrayKeys, int *numArrayKeys);
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 24d46c76dc..350dede16e 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -495,6 +495,7 @@ typedef struct IndexOnlyScan
 	List	   *indexqual;		/* list of index quals (usually OpExprs) */
 	List	   *recheckqual;	/* index quals in recheckable form */
 	List	   *indexorderby;	/* list of index ORDER BY exprs */
+	List	   *indexorderbyops;/* OIDs of sort ops for ORDER BY exprs */
 	List	   *indextlist;		/* TargetEntry list describing index's cols */
 	ScanDirection indexorderdir;	/* forward or backward or don't care */
 } IndexOnlyScan;
