|
15 | 15 | * |
16 | 16 | * |
17 | 17 | * IDENTIFICATION |
18 | | - * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.224 2007/01/3115:09:45 teodor Exp $ |
| 18 | + * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.225 2007/01/3116:54:51 teodor Exp $ |
19 | 19 | * |
20 | 20 | *------------------------------------------------------------------------- |
21 | 21 | */ |
|
76 | 76 | #include<ctype.h> |
77 | 77 | #include<math.h> |
78 | 78 |
|
79 | | -#include"access/gin.h" |
80 | 79 | #include"catalog/pg_opfamily.h" |
81 | 80 | #include"catalog/pg_statistic.h" |
82 | 81 | #include"catalog/pg_type.h" |
@@ -5287,119 +5286,6 @@ gincostestimate(PG_FUNCTION_ARGS) |
5287 | 5286 | Cost*indexTotalCost= (Cost*)PG_GETARG_POINTER(5); |
5288 | 5287 | Selectivity*indexSelectivity= (Selectivity*)PG_GETARG_POINTER(6); |
5289 | 5288 | double*indexCorrelation= (double*)PG_GETARG_POINTER(7); |
5290 | | -ListCell*l; |
5291 | | -int32nfullscan=0; |
5292 | | - |
5293 | | -/* |
5294 | | - * GIN doesn't support full index scan. |
5295 | | - * If quals require full index scan then we should |
5296 | | - * return cost big as possible to forbid full index scan. |
5297 | | - */ |
5298 | | - |
5299 | | -foreach(l,indexQuals) |
5300 | | -{ |
5301 | | -RestrictInfo*rinfo= (RestrictInfo*)lfirst(l); |
5302 | | -Expr*clause; |
5303 | | -Node*leftop, |
5304 | | -*rightop, |
5305 | | -*operand; |
5306 | | -OidextractProcOid; |
5307 | | -Oidclause_op; |
5308 | | -intstrategy_op; |
5309 | | -Oidlefttype, |
5310 | | -righttype; |
5311 | | -boolrecheck; |
5312 | | -int32nentries; |
5313 | | - |
5314 | | -/* |
5315 | | - * For each clause it's needed to check operand |
5316 | | - * for values to search in GIN. So, we should find |
5317 | | - * extractQuery method to get values from operand |
5318 | | - */ |
5319 | | - |
5320 | | -Assert(IsA(rinfo,RestrictInfo)); |
5321 | | -clause=rinfo->clause; |
5322 | | -Assert(IsA(clause,OpExpr) ); |
5323 | | -leftop=get_leftop(clause); |
5324 | | -rightop=get_rightop(clause); |
5325 | | -clause_op= ((OpExpr*)clause)->opno; |
5326 | | - |
5327 | | -if (match_index_to_operand(leftop,0/* GiN has only one column */,index)) |
5328 | | -{ |
5329 | | -operand=rightop; |
5330 | | -} |
5331 | | -elseif (match_index_to_operand(rightop,0,index)) |
5332 | | -{ |
5333 | | -operand=leftop; |
5334 | | -clause_op=get_commutator(clause_op); |
5335 | | -} |
5336 | | - |
5337 | | -if (IsA(operand,RelabelType) ) |
5338 | | -operand= (Node*) ((RelabelType*)operand)->arg; |
5339 | | - |
5340 | | -/* |
5341 | | - * It's impossible to call extractQuery method for not yet |
5342 | | - * known operand (taken from table, for example). In this |
5343 | | - * case we can't do anything useful... |
5344 | | - */ |
5345 | | -if ( !IsA(operand,Const) ) |
5346 | | -continue; |
5347 | | - |
5348 | | -if (!op_in_opfamily(clause_op,index->opfamily[0])) |
5349 | | -continue; |
5350 | | - |
5351 | | -/* |
5352 | | - * lefttype is a type of index column, righttype is a |
5353 | | - * type of operand (query) |
5354 | | - */ |
5355 | | -get_op_opfamily_properties(clause_op,index->opfamily[0], |
5356 | | -&strategy_op,&lefttype,&righttype,&recheck); |
5357 | | - |
5358 | | -/* |
5359 | | - * GIN (as GiST) always has lefttype == righttype in pg_amproc |
5360 | | - * and they are equal to type Oid on which index was created/designed |
5361 | | - */ |
5362 | | -extractProcOid=get_opfamily_proc(index->opfamily[0], |
5363 | | -lefttype,lefttype, |
5364 | | -GIN_EXTRACTQUERY_PROC ); |
5365 | | - |
5366 | | -if ( !OidIsValid(extractProcOid) ) |
5367 | | -continue;/* should not be */ |
5368 | | - |
5369 | | -OidFunctionCall3(extractProcOid, |
5370 | | -((Const*)operand)->constvalue, |
5371 | | -PointerGetDatum(&nentries), |
5372 | | -UInt16GetDatum(strategy_op)); |
5373 | | - |
5374 | | -if (nentries==0 ) |
5375 | | -nfullscan++; |
5376 | | -elseif (nentries<0 ) |
5377 | | -{ |
5378 | | -/* |
5379 | | - * GIN_EXTRACTQUERY_PROC guarantees that nothing will be found |
5380 | | - */ |
5381 | | -*indexStartupCost=0; |
5382 | | -*indexTotalCost=0; |
5383 | | -*indexSelectivity=0; |
5384 | | -*indexCorrelation=0; |
5385 | | -PG_RETURN_VOID(); |
5386 | | -} |
5387 | | -} |
5388 | | - |
5389 | | -if (nfullscan==list_length(indexQuals) ) |
5390 | | -{ |
5391 | | -/* |
5392 | | - * All quals are void and require full scan. So |
5393 | | - * set max possible cost to prevent index scan. |
5394 | | - */ |
5395 | | -*indexStartupCost=disable_cost; |
5396 | | -*indexTotalCost=disable_cost; |
5397 | | -*indexSelectivity=1.0; |
5398 | | -*indexCorrelation=0; |
5399 | | - |
5400 | | -PG_RETURN_VOID(); |
5401 | | -} |
5402 | | - |
5403 | 5289 |
|
5404 | 5290 | genericcostestimate(root,index,indexQuals,outer_rel,0.0, |
5405 | 5291 | indexStartupCost,indexTotalCost, |
|