Skip to content

Commit 5a305fe

Browse files
committed
update
1 parent 1a22134 commit 5a305fe

4 files changed

Lines changed: 344 additions & 4 deletions

File tree

postgraph--0.1.0.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ CREATE UNIQUE INDEX ag_label_relation_index
7575
ON ag_label
7676
USING btree (relation);
7777

78+
CREATE UNIQUE INDEX ag_label_vertex_adjlist_index
79+
ON ag_label
80+
USING btree (vertex_adjlist);
81+
82+
7883
CREATE UNIQUE INDEX ag_label_path_graph_index
7984
ON ag_label
8085
USING btree (label_path, graph);

src/backend/access/vertex_heap/vertex_heapam_handler.c

Lines changed: 211 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
#include "utils/builtins.h"
5151
#include "utils/rel.h"
5252

53+
#include "access/nbtree.h"
54+
#include "nodes/nodeFuncs.h"
55+
5356
#include "optimizer/plancat.h"
5457
#include "utils/inval.h"
5558
#include "access/visibilitymap.h"
@@ -79,7 +82,10 @@ uint32
7982
vertex_hash_init(Relation rel, double num_tuples, ForkNumber forkNum);
8083
void
8184
vertex_hash_doinsert(Relation rel, HeapTuple itup, Relation heapRel);
82-
85+
void
86+
vertex_exec_index_build_ScanKeys(PlanState *planstate, Relation index,
87+
List *quals,
88+
ScanKey scanKeys, int *numScanKeys);
8389
typedef struct vertex_hash_struct
8490
{
8591
graphid id; // hash key
@@ -2784,7 +2790,12 @@ static exec_seq_scan_scan_key_hook_type prev_exec_seq_scan_scan_key_hook = NULL;
27842790
void postgraph_seq_scan_key_hook (SeqScanState *node,
27852791
int *numScanKeys, ScanKey scanKeys) {
27862792

2787-
ereport(WARNING, errmsg("In hook"));
2793+
ereport(WARNING, errmsg("In hook"));
2794+
2795+
vertex_exec_index_build_ScanKeys(node, node->ss.ss_currentRelation,
2796+
node->ss.ps.plan->qual,
2797+
scanKeys, numScanKeys);
2798+
27882799
return;
27892800
}
27902801

@@ -2796,4 +2807,201 @@ void register_seq_scan_hook(void){
27962807
void unregister_seq_scan_hook(void){
27972808
exec_seq_scan_scan_key_hook = prev_exec_seq_scan_scan_key_hook;
27982809
}
2799-
2810+
2811+
2812+
2813+
2814+
/*
2815+
* ExecIndexBuildScanKeys
2816+
* Build the index scan keys from the index qualification expressions
2817+
*
2818+
* The index quals are passed to the index AM in the form of a ScanKey array.
2819+
* This routine sets up the ScanKeys, fills in all constant fields of the
2820+
* ScanKeys, and prepares information about the keys that have non-constant
2821+
* comparison values. We divide index qual expressions into five types:
2822+
*
2823+
* 1. Simple operator with constant comparison value ("indexkey op constant").
2824+
* For these, we just fill in a ScanKey containing the constant value.
2825+
*
2826+
* 2. Simple operator with non-constant value ("indexkey op expression").
2827+
* For these, we create a ScanKey with everything filled in except the
2828+
* expression value, and set up an IndexRuntimeKeyInfo struct to drive
2829+
* evaluation of the expression at the right times.
2830+
*
2831+
* 3. RowCompareExpr ("(indexkey, indexkey, ...) op (expr, expr, ...)").
2832+
* For these, we create a header ScanKey plus a subsidiary ScanKey array,
2833+
* as specified in access/skey.h. The elements of the row comparison
2834+
* can have either constant or non-constant comparison values.
2835+
*
2836+
* 4. ScalarArrayOpExpr ("indexkey op ANY (array-expression)"). If the index
2837+
* supports amsearcharray, we handle these the same as simple operators,
2838+
* setting the SK_SEARCHARRAY flag to tell the AM to handle them. Otherwise,
2839+
* we create a ScanKey with everything filled in except the comparison value,
2840+
* and set up an IndexArrayKeyInfo struct to drive processing of the qual.
2841+
* (Note that if we use an IndexArrayKeyInfo struct, the array expression is
2842+
* always treated as requiring runtime evaluation, even if it's a constant.)
2843+
*
2844+
* 5. NullTest ("indexkey IS NULL/IS NOT NULL"). We just fill in the
2845+
* ScanKey properly.
2846+
*
2847+
* This code is also used to prepare ORDER BY expressions for amcanorderbyop
2848+
* indexes. The behavior is exactly the same, except that we have to look up
2849+
* the operator differently. Note that only cases 1 and 2 are currently
2850+
* possible for ORDER BY.
2851+
*
2852+
* Input params are:
2853+
*
2854+
* planstate: executor state node we are working for
2855+
* index: the index we are building scan keys for
2856+
* quals: indexquals (or indexorderbys) expressions
2857+
* isorderby: true if processing ORDER BY exprs, false if processing quals
2858+
* *runtimeKeys: ptr to pre-existing IndexRuntimeKeyInfos, or NULL if none
2859+
* *numRuntimeKeys: number of pre-existing runtime keys
2860+
*
2861+
* Output params are:
2862+
*
2863+
* *scanKeys: receives ptr to array of ScanKeys
2864+
* *numScanKeys: receives number of scankeys
2865+
* *runtimeKeys: receives ptr to array of IndexRuntimeKeyInfos, or NULL if none
2866+
* *numRuntimeKeys: receives number of runtime keys
2867+
* *arrayKeys: receives ptr to array of IndexArrayKeyInfos, or NULL if none
2868+
* *numArrayKeys: receives number of array keys
2869+
*
2870+
* Caller may pass NULL for arrayKeys and numArrayKeys to indicate that
2871+
* IndexArrayKeyInfos are not supported.
2872+
*/
2873+
void
2874+
vertex_exec_index_build_ScanKeys(PlanState *planstate, Relation index,
2875+
List *quals,
2876+
ScanKey scanKeys, int *numScanKeys)
2877+
{
2878+
ListCell *qual_cell;
2879+
2880+
IndexRuntimeKeyInfo *runtime_keys;
2881+
int n_runtime_keys;
2882+
int max_runtime_keys;
2883+
int j;
2884+
2885+
/* Allocate array for ScanKey */
2886+
scanKeys = palloc(sizeof(IndexRuntimeKeyInfo));
2887+
2888+
/*
2889+
* runtime_keys array is dynamically resized as needed. We handle it this
2890+
* way so that the same runtime keys array can be shared between
2891+
* indexquals and indexorderbys, which will be processed in separate calls
2892+
* of this function. Caller must be sure to pass in NULL/0 for first
2893+
* call.
2894+
*/
2895+
numScanKeys = 0;
2896+
2897+
2898+
2899+
/*
2900+
* for each opclause in the given qual, convert the opclause into a single
2901+
* scan key
2902+
*/
2903+
2904+
j = 0;
2905+
foreach(qual_cell, quals)
2906+
{
2907+
Expr *clause = (Expr *) lfirst(qual_cell);
2908+
2909+
Oid opno; /* operator's OID */
2910+
RegProcedure opfuncid; /* operator proc id used in scan */
2911+
Oid opfamily; /* opfamily of index column */
2912+
int op_strategy; /* operator's strategy number */
2913+
Oid op_lefttype; /* operator's declared input types */
2914+
Oid op_righttype;
2915+
Expr *leftop; /* expr on lhs of operator */
2916+
Expr *rightop; /* expr on rhs ... */
2917+
AttrNumber varattno; /* att number used in scan */
2918+
int indnkeyatts;
2919+
2920+
indnkeyatts = 4;// id, startid, endid, properties
2921+
if (IsA(clause, OpExpr))
2922+
{
2923+
ScanKey this_scan_key = palloc(sizeof(ScanKey));
2924+
2925+
2926+
IndexRuntimeKeyInfo * runtimeKey = (IndexRuntimeKeyInfo *)scanKeys;
2927+
/* indexkey op const or indexkey op expression */
2928+
int flags = 0;
2929+
Datum scanvalue;
2930+
2931+
opno = ((OpExpr *) clause)->opno;
2932+
opfuncid = ((OpExpr *) clause)->opfuncid;
2933+
2934+
/*
2935+
* leftop should be the index key Var, possibly relabeled
2936+
*/
2937+
leftop = (Expr *) get_leftop(clause);
2938+
2939+
if (leftop && IsA(leftop, RelabelType))
2940+
leftop = ((RelabelType *) leftop)->arg;
2941+
2942+
Assert(leftop != NULL);
2943+
2944+
if (!(IsA(leftop, Var) &&
2945+
((Var *) leftop)->varno == INDEX_VAR))
2946+
elog(ERROR, "indexqual doesn't have key on left side");
2947+
2948+
varattno = ((Var *) leftop)->varattno;
2949+
if (varattno < 1 || varattno > indnkeyatts)
2950+
elog(ERROR, "bogus index qualification");
2951+
2952+
if (varattno != 1)
2953+
continue;
2954+
/*
2955+
* We have to look up the operator's strategy number. This
2956+
* provides a cross-check that the operator does match the index.
2957+
*/
2958+
opfamily = index->rd_opfamily[varattno - 1];
2959+
2960+
bool *isorderby;
2961+
get_op_opfamily_properties(opno, opfamily, isorderby,
2962+
&op_strategy,
2963+
&op_lefttype,
2964+
&op_righttype);
2965+
2966+
if (isorderby)
2967+
flags |= SK_ORDER_BY;
2968+
2969+
/*
2970+
* rightop is the constant or variable comparison value
2971+
*/
2972+
rightop = (Expr *) get_rightop(clause);
2973+
2974+
if (rightop && IsA(rightop, RelabelType))
2975+
rightop = ((RelabelType *) rightop)->arg;
2976+
2977+
Assert(rightop != NULL);
2978+
2979+
2980+
2981+
2982+
2983+
/*
2984+
* initialize the scan key's fields appropriately
2985+
*/
2986+
ScanKeyEntryInitialize(this_scan_key,
2987+
flags,
2988+
varattno, /* attribute number to scan */
2989+
op_strategy, /* op's strategy */
2990+
op_righttype, /* strategy subtype */
2991+
((OpExpr *) clause)->inputcollid, /* collation */
2992+
opfuncid, /* reg proc to use */
2993+
scanvalue); /* constant */
2994+
2995+
2996+
runtimeKey->scan_key = this_scan_key;
2997+
runtimeKey->key_expr = ExecInitExpr(rightop, planstate);
2998+
runtimeKey->key_toastable = TypeIsToastable(op_righttype);
2999+
3000+
scanvalue = (Datum) 0;
3001+
numScanKeys++;
3002+
3003+
break;
3004+
}
3005+
}
3006+
3007+
}

0 commit comments

Comments
 (0)