|
| 1 | +#include"pathman.h" |
| 2 | +#include"executor/spi.h" |
| 3 | +#include"catalog/pg_type.h" |
| 4 | + |
| 5 | +HTAB*relations=NULL; |
| 6 | +HTAB*hash_restrictions=NULL; |
| 7 | +HTAB*range_restrictions=NULL; |
| 8 | +boolinitialization_needed= true; |
| 9 | + |
| 10 | +/* |
| 11 | + * Initialize hashtables |
| 12 | + */ |
| 13 | +void |
| 14 | +init(void) |
| 15 | +{ |
| 16 | +initialization_needed= false; |
| 17 | +load_part_relations_hashtable(); |
| 18 | +// load_hash_restrictions_hashtable(); |
| 19 | +// load_range_restrictions_hashtable(); |
| 20 | +} |
| 21 | + |
| 22 | +void |
| 23 | +load_part_relations_hashtable() |
| 24 | +{ |
| 25 | +PartRelationInfo*prinfo; |
| 26 | +intret; |
| 27 | +inti; |
| 28 | +intproc; |
| 29 | +boolisnull; |
| 30 | +List*part_oids=NIL; |
| 31 | +ListCell*lc; |
| 32 | + |
| 33 | +SPI_connect(); |
| 34 | +ret=SPI_exec("SELECT pg_class.relfilenode, pg_attribute.attnum, pg_pathman_rels.parttype " |
| 35 | +"FROM pg_pathman_rels " |
| 36 | +"JOIN pg_class ON pg_class.relname = pg_pathman_rels.relname " |
| 37 | +"JOIN pg_attribute ON pg_attribute.attname = pg_pathman_rels.attname " |
| 38 | +"AND attrelid = pg_class.relfilenode",0); |
| 39 | +proc=SPI_processed; |
| 40 | + |
| 41 | +if (ret>0&&SPI_tuptable!=NULL) |
| 42 | +{ |
| 43 | +TupleDesctupdesc=SPI_tuptable->tupdesc; |
| 44 | +SPITupleTable*tuptable=SPI_tuptable; |
| 45 | + |
| 46 | +for (i=0;i<proc;i++) |
| 47 | +{ |
| 48 | +HeapTupletuple=tuptable->vals[i]; |
| 49 | + |
| 50 | +intoid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,1,&isnull)); |
| 51 | +prinfo= (PartRelationInfo*)hash_search(relations, (constvoid*)&oid,HASH_ENTER,NULL); |
| 52 | +prinfo->oid=oid; |
| 53 | +prinfo->attnum=DatumGetInt32(SPI_getbinval(tuple,tupdesc,2,&isnull)); |
| 54 | +prinfo->parttype=DatumGetInt32(SPI_getbinval(tuple,tupdesc,3,&isnull)); |
| 55 | + |
| 56 | +part_oids=lappend_int(part_oids,oid); |
| 57 | + |
| 58 | +/* children will be filled in later */ |
| 59 | +// prinfo->children = NIL; |
| 60 | +} |
| 61 | +} |
| 62 | + |
| 63 | +/* load children information */ |
| 64 | +foreach(lc,part_oids) |
| 65 | +{ |
| 66 | +Oidoid= (int)lfirst_int(lc); |
| 67 | + |
| 68 | +prinfo= (PartRelationInfo*) |
| 69 | +hash_search(relations, (constvoid*)&oid,HASH_FIND,NULL); |
| 70 | + |
| 71 | +switch(prinfo->parttype) |
| 72 | +{ |
| 73 | +casePT_RANGE: |
| 74 | +load_range_restrictions(oid); |
| 75 | +break; |
| 76 | +casePT_HASH: |
| 77 | +load_hash_restrictions(oid); |
| 78 | +break; |
| 79 | +} |
| 80 | +} |
| 81 | +SPI_finish(); |
| 82 | +} |
| 83 | + |
| 84 | +void |
| 85 | +create_part_relations_hashtable() |
| 86 | +{ |
| 87 | +HASHCTLctl; |
| 88 | + |
| 89 | +memset(&ctl,0,sizeof(ctl)); |
| 90 | +ctl.keysize=sizeof(int); |
| 91 | +ctl.entrysize=sizeof(PartRelationInfo); |
| 92 | + |
| 93 | +/* already exists, recreate */ |
| 94 | +if (relations!=NULL) |
| 95 | +hash_destroy(relations); |
| 96 | + |
| 97 | +relations=ShmemInitHash("Partitioning relation info", |
| 98 | +128,128, |
| 99 | +&ctl,HASH_ELEM |HASH_BLOBS); |
| 100 | +} |
| 101 | + |
| 102 | +void |
| 103 | +load_hash_restrictions(Oidparent_oid) |
| 104 | +{ |
| 105 | +boolfound; |
| 106 | +PartRelationInfo*prel; |
| 107 | +HashRelation*hashrel; |
| 108 | +HashRelationKeykey; |
| 109 | +intret; |
| 110 | +inti; |
| 111 | +intproc; |
| 112 | +boolisnull; |
| 113 | + |
| 114 | +Datumvals[1]; |
| 115 | +Oidoids[1]= {INT4OID}; |
| 116 | +boolnulls[1]= {false}; |
| 117 | +vals[0]=Int32GetDatum(parent_oid); |
| 118 | + |
| 119 | +prel= (PartRelationInfo*) |
| 120 | +hash_search(relations, (constvoid*)&parent_oid,HASH_FIND,&found); |
| 121 | + |
| 122 | +/* if already loaded then quit */ |
| 123 | +if (prel->children_count>0) |
| 124 | +return; |
| 125 | + |
| 126 | +ret=SPI_execute_with_args("SELECT p.relfilenode, hr.hash, c.relfilenode " |
| 127 | +"FROM pg_pathman_hash_rels hr " |
| 128 | +"JOIN pg_class p ON p.relname = hr.parent " |
| 129 | +"JOIN pg_class c ON c.relname = hr.child " |
| 130 | +"WHERE p.relfilenode = $1", |
| 131 | +1,oids,vals,nulls, true,0); |
| 132 | +proc=SPI_processed; |
| 133 | + |
| 134 | +if (ret>0&&SPI_tuptable!=NULL) |
| 135 | + { |
| 136 | +TupleDesctupdesc=SPI_tuptable->tupdesc; |
| 137 | +SPITupleTable*tuptable=SPI_tuptable; |
| 138 | + |
| 139 | +for (i=0;i<proc;i++) |
| 140 | + { |
| 141 | +HeapTupletuple=tuptable->vals[i]; |
| 142 | +intchild_oid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,3,&isnull)); |
| 143 | + |
| 144 | +key.parent_oid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,1,&isnull)); |
| 145 | +key.hash=DatumGetInt32(SPI_getbinval(tuple,tupdesc,2,&isnull)); |
| 146 | + |
| 147 | +hashrel= (HashRelation*) |
| 148 | +hash_search(hash_restrictions, (void*)&key,HASH_ENTER,&found); |
| 149 | +hashrel->child_oid=child_oid; |
| 150 | + |
| 151 | +/* appending children to PartRelationInfo */ |
| 152 | +prel->children[prel->children_count++]=child_oid; |
| 153 | + } |
| 154 | + } |
| 155 | + |
| 156 | +// SPI_finish(); |
| 157 | +} |
| 158 | + |
| 159 | +/* |
| 160 | + * Create hash restrictions table |
| 161 | + */ |
| 162 | +void |
| 163 | +create_hash_restrictions_hashtable() |
| 164 | +{ |
| 165 | +HASHCTLctl; |
| 166 | + |
| 167 | +memset(&ctl,0,sizeof(ctl)); |
| 168 | +ctl.keysize=sizeof(HashRelationKey); |
| 169 | +ctl.entrysize=sizeof(HashRelation); |
| 170 | + |
| 171 | +/* already exists, recreate */ |
| 172 | +if (hash_restrictions!=NULL) |
| 173 | +hash_destroy(hash_restrictions); |
| 174 | + |
| 175 | +hash_restrictions=ShmemInitHash("pg_pathman hash restrictions", |
| 176 | +1024,1024, |
| 177 | +&ctl,HASH_ELEM |HASH_BLOBS); |
| 178 | +} |
| 179 | + |
| 180 | +void |
| 181 | +load_range_restrictions(Oidparent_oid) |
| 182 | +{ |
| 183 | +boolfound; |
| 184 | +PartRelationInfo*prel; |
| 185 | +RangeRelation*rangerel; |
| 186 | +// HashRelation *hashrel; |
| 187 | +// HashRelationKey key; |
| 188 | +intret; |
| 189 | +inti; |
| 190 | +intproc; |
| 191 | +boolarg1_isnull,arg2_isnull; |
| 192 | + |
| 193 | +Datumvals[1]; |
| 194 | +Oidoids[1]= {INT4OID}; |
| 195 | +boolnulls[1]= {false}; |
| 196 | +vals[0]=Int32GetDatum(parent_oid); |
| 197 | + |
| 198 | +prel= (PartRelationInfo*) |
| 199 | +hash_search(relations, (constvoid*)&parent_oid,HASH_FIND,&found); |
| 200 | + |
| 201 | +/* if already loaded then quit */ |
| 202 | +if (prel->children_count>0) |
| 203 | +return; |
| 204 | + |
| 205 | +// SPI_connect(); |
| 206 | +ret=SPI_execute_with_args("SELECT p.relfilenode, c.relfilenode, " |
| 207 | +"rr.min_int, rr.max_int, rr.min_dt, rr.max_dt " |
| 208 | +"FROM pg_pathman_range_rels rr " |
| 209 | +"JOIN pg_class p ON p.relname = rr.parent " |
| 210 | +"JOIN pg_class c ON c.relname = rr.child " |
| 211 | +"WHERE p.relfilenode = $1 " |
| 212 | +"ORDER BY rr.parent, rr.min_int, rr.min_dt", |
| 213 | +1,oids,vals,nulls, true,0); |
| 214 | +proc=SPI_processed; |
| 215 | + |
| 216 | +if (ret>0&&SPI_tuptable!=NULL) |
| 217 | + { |
| 218 | +TupleDesctupdesc=SPI_tuptable->tupdesc; |
| 219 | +SPITupleTable*tuptable=SPI_tuptable; |
| 220 | + |
| 221 | +for (i=0;i<proc;i++) |
| 222 | + { |
| 223 | +Datummin; |
| 224 | +Datummax; |
| 225 | +RangeEntryre; |
| 226 | +HeapTupletuple=tuptable->vals[i]; |
| 227 | + |
| 228 | +// int parent_oid = DatumGetObjectId(SPI_getbinval(tuple, tupdesc, 1, &arg1_isnull)); |
| 229 | +re.child_oid=DatumGetObjectId(SPI_getbinval(tuple,tupdesc,2,&arg1_isnull)); |
| 230 | + |
| 231 | +rangerel= (RangeRelation*) |
| 232 | +hash_search(range_restrictions, (void*)&parent_oid,HASH_ENTER,&found); |
| 233 | + |
| 234 | +/* date */ |
| 235 | +// switch (prinfo->atttype) |
| 236 | +// { |
| 237 | +// case AT_INT: |
| 238 | +// min = SPI_getbinval(tuple, tupdesc, 3, &isnull); |
| 239 | +// max = SPI_getbinval(tuple, tupdesc, 4, &isnull); |
| 240 | +// re.min.integer = DatumGetInt32(min); |
| 241 | +// re.max.integer = DatumGetInt32(max); |
| 242 | +// break; |
| 243 | +// case AT_DATE: |
| 244 | +// min = SPI_getbinval(tuple, tupdesc, 5, &isnull); |
| 245 | +// max = SPI_getbinval(tuple, tupdesc, 6, &isnull); |
| 246 | +// re.min.date = DatumGetDateADT(min); |
| 247 | +// re.max.date = DatumGetDateADT(max); |
| 248 | +// break; |
| 249 | +// } |
| 250 | + |
| 251 | +re.min=SPI_getbinval(tuple,tupdesc,3,&arg1_isnull); |
| 252 | +re.max=SPI_getbinval(tuple,tupdesc,4,&arg2_isnull); |
| 253 | +prel->atttype=AT_INT; |
| 254 | + |
| 255 | +if (arg1_isnull||arg2_isnull) |
| 256 | +{ |
| 257 | +re.min=SPI_getbinval(tuple,tupdesc,5,&arg1_isnull); |
| 258 | +re.max=SPI_getbinval(tuple,tupdesc,6,&arg2_isnull); |
| 259 | +prel->atttype=AT_DATE; |
| 260 | + |
| 261 | +if (arg1_isnull||arg2_isnull) |
| 262 | +ereport(ERROR, (errmsg("Range relation should be of type either INTEGER or DATE"))); |
| 263 | +} |
| 264 | +rangerel->ranges[rangerel->nranges++]=re; |
| 265 | + |
| 266 | +prel->children[prel->children_count++]=re.child_oid; |
| 267 | + } |
| 268 | + } |
| 269 | + |
| 270 | +// SPI_finish(); |
| 271 | +} |
| 272 | + |
| 273 | +/* |
| 274 | + * Create range restrictions table |
| 275 | + */ |
| 276 | +void |
| 277 | +create_range_restrictions_hashtable() |
| 278 | +{ |
| 279 | +HASHCTLctl; |
| 280 | + |
| 281 | +memset(&ctl,0,sizeof(ctl)); |
| 282 | +ctl.keysize=sizeof(int); |
| 283 | +ctl.entrysize=sizeof(RangeRelation); |
| 284 | + |
| 285 | +range_restrictions=ShmemInitHash("pg_pathman range restrictions", |
| 286 | +16,16, |
| 287 | +&ctl,HASH_ELEM |HASH_BLOBS); |
| 288 | +} |