doc/src/sgml/contrib.sgml | 1 + doc/src/sgml/ctidscan.sgml | 52 ++ doc/src/sgml/filelist.sgml | 1 + src/test/modules/Makefile | 1 + src/test/modules/ctidscan/Makefile | 16 + src/test/modules/ctidscan/ctidscan.c | 808 ++++++++++++++++ src/test/modules/ctidscan/expected/ctidscan.out | 1119 +++++++++++++++++++++++ src/test/modules/ctidscan/sql/ctidscan.sql | 99 ++ src/test/regress/expected/custom_scan.out | 0 src/test/regress/sql/custom_scan.sql | 53 ++ 10 files changed, 2150 insertions(+) diff --git a/doc/src/sgml/contrib.sgml b/doc/src/sgml/contrib.sgml index a698d0f..59eab97 100644 --- a/doc/src/sgml/contrib.sgml +++ b/doc/src/sgml/contrib.sgml @@ -109,6 +109,7 @@ CREATE EXTENSION module_name FROM unpackaged; &btree-gist; &chkpass; &citext; + &ctidscan; &cube; &dblink; &dict-int; diff --git a/doc/src/sgml/ctidscan.sgml b/doc/src/sgml/ctidscan.sgml new file mode 100644 index 0000000..fa21b0f --- /dev/null +++ b/doc/src/sgml/ctidscan.sgml @@ -0,0 +1,52 @@ + + + + ctidscan + + + ctidscan + + + + This module implements a custom-scan provider that utilizes inequality + operator that involves the ctid system column. + + + + This module provides no SQL accessible interface. For installation, + all you need to do is just load the module to the server. + + You can load it an individual session using: + +LOAD 'ctidscan'; + + + or, you can also take more typical usage with extension preloading + using or + in + postgresql.conf. + + Then, planner may consider more cheap execution path if supplied query + involves above operators. + + + + + enable_ctidscan (bool) + + enable_ctidscan configuration parameter + + + + + enable_ctidscan turns on/off functionality of + ctidscan custom-scan provider. + If turned off, it does not offer alternative scan path even if + supplied query is sufficient to run by ctidscan plan. + Its default is true. + Anybody can change using SET command. + + + + + diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index f03b72a..15d569e 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -107,6 +107,7 @@ + diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 93d93af..c288276 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -6,6 +6,7 @@ include $(top_builddir)/src/Makefile.global SUBDIRS = \ commit_ts \ + ctidscan \ worker_spi \ dummy_seclabel \ test_shm_mq \ diff --git a/src/test/modules/ctidscan/Makefile b/src/test/modules/ctidscan/Makefile new file mode 100644 index 0000000..bbe280a --- /dev/null +++ b/src/test/modules/ctidscan/Makefile @@ -0,0 +1,16 @@ +# contrib/ctidscan/Makefile + +MODULES = ctidscan + +REGRESS = ctidscan + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/ctidscan +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/ctidscan/ctidscan.c b/src/test/modules/ctidscan/ctidscan.c new file mode 100644 index 0000000..85b8304 --- /dev/null +++ b/src/test/modules/ctidscan/ctidscan.c @@ -0,0 +1,808 @@ +/* + * ctidscan.c + * + * A custom-scan provide that utilizes ctid system column within + * inequality-operators, to skip block reads never referenced. + * + * It is designed to demonstrate Custom Scan APIs; that allows to override + * a part of executor node. This extension focus on a workload that tries + * to fetch records with tid larger or less than a particular value. + * In case when inequality operators were given, this module construct + * a custom scan path that enables to skip records not to be read. Then, + * if it was the cheapest one, it shall be used to run the query. + * Custom Scan APIs callbacks this extension when executor tries to fetch + * underlying records, then it utilizes existing heap_getnext() but seek + * the records to be read prior to fetching the first record. + * + * Portions Copyright (c) 2014, PostgreSQL Global Development Group + */ +#include "postgres.h" +#include "access/relscan.h" +#include "access/sysattr.h" +#include "catalog/pg_operator.h" +#include "catalog/pg_type.h" +#include "commands/defrem.h" +#include "commands/explain.h" +#include "executor/executor.h" +#include "executor/nodeCustom.h" +#include "fmgr.h" +#include "miscadmin.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/clauses.h" +#include "optimizer/cost.h" +#include "optimizer/paths.h" +#include "optimizer/pathnode.h" +#include "optimizer/plancat.h" +#include "optimizer/planmain.h" +#include "optimizer/placeholder.h" +#include "optimizer/restrictinfo.h" +#include "optimizer/subselect.h" +#include "parser/parsetree.h" +#include "storage/bufmgr.h" +#include "storage/itemptr.h" +#include "utils/builtins.h" +#include "utils/fmgroids.h" +#include "utils/guc.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/rel.h" +#include "utils/ruleutils.h" +#include "utils/spccache.h" + +/* missing declaration in pg_proc.h */ +#ifndef TIDGreaterOperator +#define TIDGreaterOperator 2800 +#endif +#ifndef TIDLessEqualOperator +#define TIDLessEqualOperator 2801 +#endif +#ifndef TIDGreaterEqualOperator +#define TIDGreaterEqualOperator 2802 +#endif + +PG_MODULE_MAGIC; + +/* + * NOTE: We don't use any special data type to save the private data. + * All we want to save in private fields is expression-list that shall + * be adjusted by setrefs.c/subselect.c, so we put it on the custom_exprs + * of CustomScan structure, not custom_private field. + * Due to the interface contract, only expression nodes are allowed to put + * on the custom_exprs, and we have to pay attention the core backend may + * adjust expression items. + */ + +/* + * CtidScanState - state object of ctidscan on executor. + * It has few additional internal state. The 'ctid_quals' has list of + * ExprState for inequality operators that involve ctid system column. + */ +typedef struct { + CustomScanState css; + List *ctid_quals; /* list of ExprState for inequality ops */ +} CtidScanState; + +/* static variables */ +static bool enable_ctidscan; +static set_rel_pathlist_hook_type set_rel_pathlist_next = NULL; + +/* function declarations */ +void _PG_init(void); + +static void SetCtidScanPath(PlannerInfo *root, + RelOptInfo *rel, + Index rti, + RangeTblEntry *rte); +/* CustomPathMethods */ +static Plan *PlanCtidScanPath(PlannerInfo *root, + RelOptInfo *rel, + CustomPath *best_path, + List *tlist, + List *clauses); + +/* CustomScanMethods */ +static Node *CreateCtidScanState(CustomScan *custom_plan); + +/* CustomScanExecMethods */ +static void BeginCtidScan(CustomScanState *node, EState *estate, int eflags); +static void ReScanCtidScan(CustomScanState *node); +static TupleTableSlot *ExecCtidScan(CustomScanState *node); +static void EndCtidScan(CustomScanState *node); +static void ExplainCtidScan(CustomScanState *node, List *ancestors, + ExplainState *es); + +/* static table of custom-scan callbacks */ +static CustomPathMethods ctidscan_path_methods = { + "ctidscan", /* CustomName */ + PlanCtidScanPath, /* PlanCustomPath */ + NULL, /* TextOutCustomPath */ +}; + +static CustomScanMethods ctidscan_scan_methods = { + "ctidscan", /* CustomName */ + CreateCtidScanState, /* CreateCustomScanState */ + NULL, /* TextOutCustomScan */ +}; + +static CustomExecMethods ctidscan_exec_methods = { + "ctidscan", /* CustomName */ + BeginCtidScan, /* BeginCustomScan */ + ExecCtidScan, /* ExecCustomScan */ + EndCtidScan, /* EndCustomScan */ + ReScanCtidScan, /* ReScanCustomScan */ + NULL, /* MarkPosCustomScan */ + NULL, /* RestrPosCustomScan */ + ExplainCtidScan, /* ExplainCustomScan */ +}; + +#define IsCTIDVar(node,rtindex) \ + ((node) != NULL && \ + IsA((node), Var) && \ + ((Var *) (node))->varno == (rtindex) && \ + ((Var *) (node))->varattno == SelfItemPointerAttributeNumber && \ + ((Var *) (node))->varlevelsup == 0) + +/* + * CTidQualFromExpr + * + * It checks whether the given restriction clauses enables to determine + * the zone to be scanned, or not. If one or more restriction clauses are + * available, it returns a list of them, or NIL elsewhere. + * The caller can consider all the conditions are chained with AND- + * boolean operator, so all the operator works for narrowing down the + * scope of custom tid scan. + */ +static List * +CTidQualFromExpr(Node *expr, int varno) +{ + if (is_opclause(expr)) + { + OpExpr *op = (OpExpr *) expr; + Node *arg1; + Node *arg2; + Node *other = NULL; + + /* only inequality operators are candidate */ + if (op->opno != TIDLessOperator && + op->opno != TIDLessEqualOperator && + op->opno != TIDGreaterOperator && + op->opno != TIDGreaterEqualOperator) + return NULL; + + if (list_length(op->args) != 2) + return false; /* should not happen */ + + arg1 = linitial(op->args); + arg2 = lsecond(op->args); + + if (IsCTIDVar(arg1, varno)) + other = arg2; + else if (IsCTIDVar(arg2, varno)) + other = arg1; + else + return NULL; + if (exprType(other) != TIDOID) + return NULL; /* should not happen */ + /* The other argument must be a pseudoconstant */ + if (!is_pseudo_constant_clause(other)) + return NULL; + + return list_make1(copyObject(op)); + } + else if (and_clause(expr)) + { + List *rlst = NIL; + ListCell *lc; + + foreach(lc, ((BoolExpr *) expr)->args) + { + List *temp = CTidQualFromExpr((Node *) lfirst(lc), varno); + + rlst = list_concat(rlst, temp); + } + return rlst; + } + return NIL; +} + +/* + * CTidEstimateCosts + * + * It estimates cost to scan the target relation according to the given + * restriction clauses. Its logic to scan relations are almost same as + * SeqScan doing, because it uses regular heap_getnext(), except for + * the number of tuples to be scanned if restriction clauses work well. +*/ +static void +CTidEstimateCosts(PlannerInfo *root, + RelOptInfo *baserel, + CustomPath *cpath) +{ + Path *path = &cpath->path; + List *ctid_quals = cpath->custom_private; + ListCell *lc; + double ntuples; + ItemPointerData ip_min; + ItemPointerData ip_max; + bool has_min_val = false; + bool has_max_val = false; + BlockNumber num_pages; + Cost startup_cost = 0; + Cost run_cost = 0; + Cost cpu_per_tuple; + QualCost qpqual_cost; + QualCost ctid_qual_cost; + double spc_random_page_cost; + + /* Should only be applied to base relations */ + Assert(baserel->relid > 0); + Assert(baserel->rtekind == RTE_RELATION); + + /* Mark the path with the correct row estimate */ + if (path->param_info) + path->rows = path->param_info->ppi_rows; + else + path->rows = baserel->rows; + + /* Estimate how many tuples we may retrieve */ + ItemPointerSet(&ip_min, 0, 0); + ItemPointerSet(&ip_max, MaxBlockNumber, MaxOffsetNumber); + foreach (lc, ctid_quals) + { + OpExpr *op = lfirst(lc); + Oid opno; + Node *other; + + Assert(is_opclause(op)); + if (IsCTIDVar(linitial(op->args), baserel->relid)) + { + opno = op->opno; + other = lsecond(op->args); + } + else if (IsCTIDVar(lsecond(op->args), baserel->relid)) + { + /* To simplifies, we assume as if Var node is 1st argument */ + opno = get_commutator(op->opno); + other = linitial(op->args); + } + else + elog(ERROR, "could not identify CTID variable"); + + if (IsA(other, Const)) + { + ItemPointer ip = (ItemPointer)(((Const *) other)->constvalue); + + /* + * Just an rough estimation, we don't distinct inequality and + * inequality-or-equal operator from scan-size estimation + * perspective. + */ + switch (opno) + { + case TIDLessOperator: + case TIDLessEqualOperator: + if (ItemPointerCompare(ip, &ip_max) < 0) + ItemPointerCopy(ip, &ip_max); + has_max_val = true; + break; + case TIDGreaterOperator: + case TIDGreaterEqualOperator: + if (ItemPointerCompare(ip, &ip_min) > 0) + ItemPointerCopy(ip, &ip_min); + has_min_val = true; + break; + default: + elog(ERROR, "unexpected operator code: %u", op->opno); + break; + } + } + } + + /* estimated number of tuples in this relation */ + ntuples = baserel->pages * baserel->tuples; + + if (has_min_val && has_max_val) + { + /* case of both side being bounded */ + BlockNumber bnum_max = BlockIdGetBlockNumber(&ip_max.ip_blkid); + BlockNumber bnum_min = BlockIdGetBlockNumber(&ip_min.ip_blkid); + + bnum_max = Min(bnum_max, baserel->pages); + bnum_min = Max(bnum_min, 0); + num_pages = Min(bnum_max - bnum_min + 1, 1); + } + else if (has_min_val) + { + /* case of only lower side being bounded */ + BlockNumber bnum_max = baserel->pages; + BlockNumber bnum_min = BlockIdGetBlockNumber(&ip_min.ip_blkid); + + bnum_min = Max(bnum_min, 0); + num_pages = Min(bnum_max - bnum_min + 1, 1); + } + else if (has_max_val) + { + /* case of only upper side being bounded */ + BlockNumber bnum_max = BlockIdGetBlockNumber(&ip_max.ip_blkid); + BlockNumber bnum_min = 0; + + bnum_max = Min(bnum_max, baserel->pages); + num_pages = Min(bnum_max - bnum_min + 1, 1); + } + else + { + /* + * Just a rough estimation. We assume half of records shall be + * read using this restriction clause, but indeterministic until + * executor run it actually. + */ + num_pages = Max((baserel->pages + 1) / 2, 1); + } + ntuples *= ((double) num_pages) / ((double) baserel->pages); + + /* + * The TID qual expressions will be computed once, any other baserestrict + * quals once per retrieved tuple. + */ + cost_qual_eval(&ctid_qual_cost, ctid_quals, root); + + /* fetch estimated page cost for tablespace containing table */ + get_tablespace_page_costs(baserel->reltablespace, + &spc_random_page_cost, + NULL); + + /* disk costs --- assume each tuple on a different page */ + run_cost += spc_random_page_cost * ntuples; + + /* + * Add scanning CPU costs + * (logic copied from get_restriction_qual_cost) + */ + if (path->param_info) + { + /* Include costs of pushed-down clauses */ + cost_qual_eval(&qpqual_cost, path->param_info->ppi_clauses, root); + + qpqual_cost.startup += baserel->baserestrictcost.startup; + qpqual_cost.per_tuple += baserel->baserestrictcost.per_tuple; + } + else + qpqual_cost = baserel->baserestrictcost; + + /* + * We don't decrease cost for the inequality operators, because + * it is subset of qpquals and still in. + */ + startup_cost += qpqual_cost.startup + ctid_qual_cost.per_tuple; + cpu_per_tuple = cpu_tuple_cost + qpqual_cost.per_tuple - + ctid_qual_cost.per_tuple; + run_cost = cpu_per_tuple * ntuples; + + path->startup_cost = startup_cost; + path->total_cost = startup_cost + run_cost; +} + +/* + * SetCtidScanPath - entrypoint of the series of custom-scan execution. + * It adds CustomPath if referenced relation has inequality expressions on + * the ctid system column. + */ +static void +SetCtidScanPath(PlannerInfo *root, RelOptInfo *baserel, + Index rtindex, RangeTblEntry *rte) +{ + char relkind; + ListCell *lc; + List *ctid_quals = NIL; + + /* only plain relations are supported */ + if (rte->rtekind != RTE_RELATION) + return; + relkind = get_rel_relkind(rte->relid); + if (relkind != RELKIND_RELATION && + relkind != RELKIND_MATVIEW && + relkind != RELKIND_TOASTVALUE) + return; + + /* + * NOTE: Unlike built-in execution path, always we can have core path + * even though ctid scan is not available. So, simply, we don't add + * any paths, instead of adding disable_cost. + */ + if (!enable_ctidscan) + return; + + /* walk on the restrict info */ + foreach (lc, baserel->baserestrictinfo) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + List *temp; + + if (!IsA(rinfo, RestrictInfo)) + continue; /* probably should never happen */ + temp = CTidQualFromExpr((Node *) rinfo->clause, baserel->relid); + ctid_quals = list_concat(ctid_quals, temp); + } + + /* + * OK, it is case when a part of restriction clause makes sense to + * reduce number of tuples, so we will add a custom scan path being + * provided by this module. + */ + if (ctid_quals != NIL) + { + CustomPath *cpath; + Relids required_outer; + + /* + * We don't support pushing join clauses into the quals of a ctidscan, + * but it could still have required parameterization due to LATERAL + * refs in its tlist. + */ + required_outer = baserel->lateral_relids; + + cpath = palloc0(sizeof(CustomPath)); + cpath->path.type = T_CustomPath; + cpath->path.pathtype = T_CustomScan; + cpath->path.parent = baserel; + cpath->path.param_info + = get_baserel_parampathinfo(root, baserel, required_outer); + cpath->flags = CUSTOMPATH_SUPPORT_BACKWARD_SCAN; + cpath->custom_private = ctid_quals; + cpath->methods = &ctidscan_path_methods; + + CTidEstimateCosts(root, baserel, cpath); + + add_path(baserel, &cpath->path); + } +} + +/* + * PlanCtidScanPlan - A method of CustomPath; that populate a custom + * object being delivered from CustomScan type, according to the supplied + * CustomPath object. + */ +static Plan * +PlanCtidScanPath(PlannerInfo *root, + RelOptInfo *rel, + CustomPath *best_path, + List *tlist, + List *clauses) +{ + List *ctid_quals = best_path->custom_private; + CustomScan *cscan = makeNode(CustomScan); + + cscan->flags = best_path->flags; + cscan->methods = &ctidscan_scan_methods; + + /* set scanrelid */ + cscan->scan.scanrelid = rel->relid; + /* set targetlist as is */ + cscan->scan.plan.targetlist = tlist; + /* reduce RestrictInfo list to bare expressions */ + cscan->scan.plan.qual = extract_actual_clauses(clauses, false); + /* set ctid related quals */ + cscan->custom_exprs = ctid_quals; + + return &cscan->scan.plan; +} + +/* + * CreateCtidScanState - A method of CustomScan; that populate a custom + * object being delivered from CustomScanState type, according to the + * supplied CustomPath object. + */ +static Node * +CreateCtidScanState(CustomScan *custom_plan) +{ + CtidScanState *ctss = palloc0(sizeof(CtidScanState)); + + NodeSetTag(ctss, T_CustomScanState); + ctss->css.flags = custom_plan->flags; + ctss->css.methods = &ctidscan_exec_methods; + + return (Node *)&ctss->css; +} + +/* + * BeginCtidScan - A method of CustomScanState; that initializes + * the supplied CtidScanState object, at beginning of the executor. + */ +static void +BeginCtidScan(CustomScanState *node, EState *estate, int eflags) +{ + CtidScanState *ctss = (CtidScanState *) node; + CustomScan *cscan = (CustomScan *) node->ss.ps.plan; + + /* + * In case of custom-scan provider that offers an alternative way + * to scan a particular relation, most of the needed initialization, + * like relation open or assignment of scan tuple-slot or projection + * info, shall be done by the core implementation. So, all we need + * to have is initialization of own local properties. + */ + ctss->ctid_quals = (List *) + ExecInitExpr((Expr *)cscan->custom_exprs, &node->ss.ps); +} + +/* + * ReScanCtidScan - A method of CustomScanState; that rewind the current + * seek position. + */ +static void +ReScanCtidScan(CustomScanState *node) +{ + CtidScanState *ctss = (CtidScanState *)node; + HeapScanDesc scan = ctss->css.ss.ss_currentScanDesc; + EState *estate = node->ss.ps.state; + ScanDirection direction = estate->es_direction; + Relation relation = ctss->css.ss.ss_currentRelation; + ExprContext *econtext = ctss->css.ss.ps.ps_ExprContext; + ScanKeyData keys[2]; + bool has_ubound = false; + bool has_lbound = false; + ItemPointerData ip_max; + ItemPointerData ip_min; + ListCell *lc; + + /* once close the existing scandesc, if any */ + if (scan) + { + heap_endscan(scan); + scan = ctss->css.ss.ss_currentScanDesc = NULL; + } + + /* walks on the inequality operators */ + foreach (lc, ctss->ctid_quals) + { + FuncExprState *fexstate = (FuncExprState *) lfirst(lc); + OpExpr *op = (OpExpr *)fexstate->xprstate.expr; + Node *arg1 = linitial(op->args); + Node *arg2 = lsecond(op->args); + Index scanrelid; + Oid opno; + ExprState *exstate; + ItemPointer itemptr; + bool isnull; + + scanrelid = ((Scan *)ctss->css.ss.ps.plan)->scanrelid; + if (IsCTIDVar(arg1, scanrelid)) + { + exstate = (ExprState *) lsecond(fexstate->args); + opno = op->opno; + } + else if (IsCTIDVar(arg2, scanrelid)) + { + exstate = (ExprState *) linitial(fexstate->args); + opno = get_commutator(op->opno); + } + else + elog(ERROR, "could not identify CTID variable"); + + itemptr = (ItemPointer) + DatumGetPointer(ExecEvalExprSwitchContext(exstate, + econtext, + &isnull, + NULL)); + if (isnull) + { + /* + * Whole of the restriction clauses chained with AND- boolean + * operators because false, if one of the clauses has NULL result. + * So, we can immediately break the evaluation to inform caller + * it does not make sense to scan any more. + * In this case, scandesc is kept to NULL. + */ + return; + } + + switch (opno) + { + case TIDLessOperator: + if (!has_ubound || + ItemPointerCompare(itemptr, &ip_max) <= 0) + { + ScanKeyInit(&keys[0], + SelfItemPointerAttributeNumber, + BTLessStrategyNumber, + F_TIDLT, + PointerGetDatum(itemptr)); + ItemPointerCopy(itemptr, &ip_max); + has_ubound = true; + } + break; + + case TIDLessEqualOperator: + if (!has_ubound || + ItemPointerCompare(itemptr, &ip_max) < 0) + { + ScanKeyInit(&keys[0], + SelfItemPointerAttributeNumber, + BTLessEqualStrategyNumber, + F_TIDLE, + PointerGetDatum(itemptr)); + ItemPointerCopy(itemptr, &ip_max); + has_ubound = true; + } + break; + + case TIDGreaterOperator: + if (!has_lbound || + ItemPointerCompare(itemptr, &ip_min) >= 0) + { + ScanKeyInit(&keys[1], + SelfItemPointerAttributeNumber, + BTGreaterStrategyNumber, + F_TIDGT, + PointerGetDatum(itemptr)); + ItemPointerCopy(itemptr, &ip_min); + has_lbound = true; + } + break; + + case TIDGreaterEqualOperator: + if (!has_lbound || + ItemPointerCompare(itemptr, &ip_min) > 0) + { + ScanKeyInit(&keys[1], + SelfItemPointerAttributeNumber, + BTGreaterEqualStrategyNumber, + F_TIDGE, + PointerGetDatum(itemptr)); + ItemPointerCopy(itemptr, &ip_min); + has_lbound = true; + } + break; + + default: + elog(ERROR, "unsupported operator"); + break; + } + } + + /* begin heapscan with the key above */ + if (has_ubound && has_lbound) + scan = heap_beginscan(relation, estate->es_snapshot, 2, &keys[0]); + else if (has_ubound) + scan = heap_beginscan(relation, estate->es_snapshot, 1, &keys[0]); + else if (has_lbound) + scan = heap_beginscan(relation, estate->es_snapshot, 1, &keys[1]); + else + scan = heap_beginscan(relation, estate->es_snapshot, 0, NULL); + + /* Seek the starting position, if possible */ + if (direction == ForwardScanDirection && has_lbound) + { + BlockNumber blknum = Min(BlockIdGetBlockNumber(&ip_min.ip_blkid), + scan->rs_nblocks - 1); + scan->rs_startblock = blknum; + } + else if (direction == BackwardScanDirection && has_ubound) + { + BlockNumber blknum = Min(BlockIdGetBlockNumber(&ip_max.ip_blkid), + scan->rs_nblocks - 1); + scan->rs_startblock = blknum; + } + ctss->css.ss.ss_currentScanDesc = scan; +} + +/* + * CTidAccessCustomScan + * + * Access method of ExecCtidScan below. It fetches a tuple from the underlying + * heap scan that was started from the point according to the tid clauses. + */ +static TupleTableSlot * +CTidAccessCustomScan(CustomScanState *node) +{ + CtidScanState *ctss = (CtidScanState *) node; + HeapScanDesc scan; + TupleTableSlot *slot; + EState *estate = node->ss.ps.state; + ScanDirection direction = estate->es_direction; + HeapTuple tuple; + + if (!ctss->css.ss.ss_currentScanDesc) + ReScanCtidScan(node); + scan = ctss->css.ss.ss_currentScanDesc; + Assert(scan != NULL); + + /* + * get the next tuple from the table + */ + tuple = heap_getnext(scan, direction); + if (!HeapTupleIsValid(tuple)) + return NULL; + + slot = ctss->css.ss.ss_ScanTupleSlot; + ExecStoreTuple(tuple, slot, scan->rs_cbuf, false); + + return slot; +} + +static bool +CTidRecheckCustomScan(CustomScanState *node, TupleTableSlot *slot) +{ + return true; +} + +/* + * ExecCtidScan - A method of CustomScanState; that fetches a tuple + * from the relation, if exist anymore. + */ +static TupleTableSlot * +ExecCtidScan(CustomScanState *node) +{ + return ExecScan(&node->ss, + (ExecScanAccessMtd) CTidAccessCustomScan, + (ExecScanRecheckMtd) CTidRecheckCustomScan); +} + +/* + * CTidEndCustomScan - A method of CustomScanState; that closes heap and + * scan descriptor, and release other related resources. + */ +static void +EndCtidScan(CustomScanState *node) +{ + CtidScanState *ctss = (CtidScanState *)node; + + if (ctss->css.ss.ss_currentScanDesc) + heap_endscan(ctss->css.ss.ss_currentScanDesc); +} + +/* + * ExplainCtidScan - A method of CustomScanState; that shows extra info + * on EXPLAIN command. + */ +static void +ExplainCtidScan(CustomScanState *node, List *ancestors, ExplainState *es) +{ + CtidScanState *ctss = (CtidScanState *) node; + CustomScan *cscan = (CustomScan *) ctss->css.ss.ps.plan; + + /* logic copied from show_qual and show_expression */ + if (cscan->custom_exprs) + { + bool useprefix = es->verbose; + Node *qual; + List *context; + char *exprstr; + + /* Convert AND list to explicit AND */ + qual = (Node *) make_ands_explicit(cscan->custom_exprs); + + /* Set up deparsing context */ + context = deparse_context_for_planstate((Node *)&node->ss.ps, + ancestors, + es->rtable, + es->rtable_names); + + /* Deparse the expression */ + exprstr = deparse_expression(qual, context, useprefix, false); + + /* And add to es->str */ + ExplainPropertyText("ctid quals", exprstr, es); + } +} + +/* + * Entrypoint of this extension + */ +void +_PG_init(void) +{ + DefineCustomBoolVariable("enable_ctidscan", + "Enables the planner's use of ctid-scan plans.", + NULL, + &enable_ctidscan, + true, + PGC_USERSET, + GUC_NOT_IN_SAMPLE, + NULL, NULL, NULL); + + /* registration of the hook to add alternative path */ + set_rel_pathlist_next = set_rel_pathlist_hook; + set_rel_pathlist_hook = SetCtidScanPath; +} diff --git a/src/test/modules/ctidscan/expected/ctidscan.out b/src/test/modules/ctidscan/expected/ctidscan.out new file mode 100644 index 0000000..90db9aa --- /dev/null +++ b/src/test/modules/ctidscan/expected/ctidscan.out @@ -0,0 +1,1119 @@ +-- +-- Regression Tests for CustomScan Interface with CtidScan Provider +-- +-- construction of test data +SET client_min_messages TO 'warning'; +SET SEED TO 0.20140702; +CREATE SCHEMA regtest_custom_scan; +SET search_path TO regtest_custom_scan, public; +CREATE TABLE t1 ( + a int primary key, + b float, + c text +); +INSERT INTO t1 (SELECT i, ceil(random()*10000.0) / 1000.0, md5(i::text) FROM generate_series(1,1000) i); +VACUUM ANALYZE t1; +CREATE TABLE t2 ( + x int primary key, + y float, + z text +); +INSERT INTO t2 (SELECT i, ceil(random()*10000.0) / 1000.0, md5((-i)::text) FROM generate_series(201,1200) i); +VACUUM ANALYZE t2; +CREATE TABLE t3 ( + a int references t1(a), + x int references t2(x) +); +INSERT INTO t3 (SELECT ceil(random() * 1000), ceil(random() * 1000) + 200 FROM generate_series(1,8000) i); +RESET client_min_messages; +-- +-- Check Plans if no special extensions are loaded. +-- +EXPLAIN (costs off) SELECT * FROM t1 WHERE a = 40 AND ctid < '(6,0)'::tid; + QUERY PLAN +--------------------------------- + Index Scan using t1_pkey on t1 + Index Cond: (a = 40) + Filter: (ctid < '(6,0)'::tid) +(3 rows) + +EXPLAIN (costs off) SELECT * FROM t1 WHERE c like '%789%' AND ctid < '(5,0)'::tid; + QUERY PLAN +------------------------------------------------------------ + Seq Scan on t1 + Filter: ((c ~~ '%789%'::text) AND (ctid < '(5,0)'::tid)) +(2 rows) + +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid = '(2,10)'::tid; + QUERY PLAN +------------------------------------ + Tid Scan on t1 + TID Cond: (ctid = '(2,10)'::tid) +(2 rows) + +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; + QUERY PLAN +------------------------------------------------------------------ + Seq Scan on t1 + Filter: ((ctid >= '(2,115)'::tid) AND (ctid <= '(3,10)'::tid)) +(2 rows) + +EXPLAIN (costs off) + SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND t2.x = t3.x + AND t1.ctid BETWEEN '(3,10)'::tid AND '(10,9999)'::tid + AND t2.ctid BETWEEN '(4,9999)'::tid AND '(8,0)'::tid + AND t3.ctid BETWEEN '(2,0)'::tid AND '(5,0)'::tid; + QUERY PLAN +-------------------------------------------------------------------------------------- + Nested Loop + -> Hash Join + Hash Cond: (t3.a = t1.a) + -> Seq Scan on t3 + Filter: ((ctid >= '(2,0)'::tid) AND (ctid <= '(5,0)'::tid)) + -> Hash + -> Seq Scan on t1 + Filter: ((ctid >= '(3,10)'::tid) AND (ctid <= '(10,9999)'::tid)) + -> Index Scan using t2_pkey on t2 + Index Cond: (x = t3.x) + Filter: ((ctid >= '(4,9999)'::tid) AND (ctid <= '(8,0)'::tid)) +(11 rows) + +EXPLAIN (costs off, verbose) + SELECT count(*), ceil(b) + FROM t1 WHERE ctid BETWEEN '(3,0)'::tid AND '(10,0)'::tid + GROUP BY ceil(b); + QUERY PLAN +---------------------------------------------------------------------------- + HashAggregate + Output: count(*), (ceil(b)) + Group Key: ceil(t1.b) + -> Seq Scan on regtest_custom_scan.t1 + Output: ceil(b) + Filter: ((t1.ctid >= '(3,0)'::tid) AND (t1.ctid <= '(10,0)'::tid)) +(6 rows) + +-- +-- Plan for same query but ctidscan was loaded +-- +LOAD '$libdir/ctidscan'; +EXPLAIN (costs off) SELECT * FROM t1 WHERE a = 40 AND ctid < '(6,0)'::tid; + QUERY PLAN +--------------------------------- + Index Scan using t1_pkey on t1 + Index Cond: (a = 40) + Filter: (ctid < '(6,0)'::tid) +(3 rows) + +EXPLAIN (costs off) SELECT * FROM t1 WHERE c like '%789%' AND ctid < '(5,0)'::tid; + QUERY PLAN +------------------------------------------------------------ + Custom Scan (ctidscan) on t1 + Filter: ((c ~~ '%789%'::text) AND (ctid < '(5,0)'::tid)) + ctid quals: (ctid < '(5,0)'::tid) +(3 rows) + +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid = '(2,10)'::tid; + QUERY PLAN +------------------------------------ + Tid Scan on t1 + TID Cond: (ctid = '(2,10)'::tid) +(2 rows) + +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; + QUERY PLAN +---------------------------------------------------------------------- + Custom Scan (ctidscan) on t1 + Filter: ((ctid >= '(2,115)'::tid) AND (ctid <= '(3,10)'::tid)) + ctid quals: ((ctid >= '(2,115)'::tid) AND (ctid <= '(3,10)'::tid)) +(3 rows) + +EXPLAIN (costs off) + SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND t2.x = t3.x + AND t1.ctid BETWEEN '(3,10)'::tid AND '(10,9999)'::tid + AND t2.ctid BETWEEN '(4,9999)'::tid AND '(8,0)'::tid + AND t3.ctid BETWEEN '(2,0)'::tid AND '(5,0)'::tid; + QUERY PLAN +------------------------------------------------------------------------------------------ + Nested Loop + -> Hash Join + Hash Cond: (t3.a = t1.a) + -> Custom Scan (ctidscan) on t3 + Filter: ((ctid >= '(2,0)'::tid) AND (ctid <= '(5,0)'::tid)) + ctid quals: ((ctid >= '(2,0)'::tid) AND (ctid <= '(5,0)'::tid)) + -> Hash + -> Custom Scan (ctidscan) on t1 + Filter: ((ctid >= '(3,10)'::tid) AND (ctid <= '(10,9999)'::tid)) + ctid quals: ((ctid >= '(3,10)'::tid) AND (ctid <= '(10,9999)'::tid)) + -> Index Scan using t2_pkey on t2 + Index Cond: (x = t3.x) + Filter: ((ctid >= '(4,9999)'::tid) AND (ctid <= '(8,0)'::tid)) +(13 rows) + +EXPLAIN (costs off, verbose) + SELECT count(*), ceil(b) + FROM t1 WHERE ctid BETWEEN '(3,0)'::tid AND '(10,0)'::tid + GROUP BY ceil(b); + QUERY PLAN +-------------------------------------------------------------------------------- + HashAggregate + Output: count(*), (ceil(b)) + Group Key: ceil(t1.b) + -> Custom Scan (ctidscan) on regtest_custom_scan.t1 + Output: ceil(b) + Filter: ((t1.ctid >= '(3,0)'::tid) AND (t1.ctid <= '(10,0)'::tid)) + ctid quals: ((t1.ctid >= '(3,0)'::tid) AND (t1.ctid <= '(10,0)'::tid)) +(7 rows) + +-- +-- Run the query without EXPLAIN +-- +SELECT ctid,* FROM t1 WHERE ctid <= '(1,20)'::tid; + ctid | a | b | c +--------+-----+-------+---------------------------------- + (0,1) | 1 | 2.727 | c4ca4238a0b923820dcc509a6f75849b + (0,2) | 2 | 7.903 | c81e728d9d4c2f636f067f89cc14862c + (0,3) | 3 | 9.098 | eccbc87e4b5ce2fe28308fd9f2a7baf3 + (0,4) | 4 | 0.488 | a87ff679a2f3e71d9181a67b7542122c + (0,5) | 5 | 4.796 | e4da3b7fbbce2345d7772b0674a318d5 + (0,6) | 6 | 1.83 | 1679091c5a880faf6fb5e6087eb1b2dc + (0,7) | 7 | 5.628 | 8f14e45fceea167a5a36dedd4bea2543 + (0,8) | 8 | 8.416 | c9f0f895fb98ab9159f51fd0297e236d + (0,9) | 9 | 5.311 | 45c48cce2e2d7fbdea1afc51c7c6ad26 + (0,10) | 10 | 1.431 | d3d9446802a44259755d38e6d163e820 + (0,11) | 11 | 9.431 | 6512bd43d9caa6e02c990b0a82652dca + (0,12) | 12 | 6.578 | c20ad4d76fe97759aa27a0c99bff6710 + (0,13) | 13 | 0.996 | c51ce410c124a10e0db5e4b97fc2af39 + (0,14) | 14 | 2.613 | aab3238922bcc25a6f606eb525ffdc56 + (0,15) | 15 | 8.43 | 9bf31c7ff062936a96d3c8bd1f8f2ff3 + (0,16) | 16 | 2.64 | c74d97b01eae257e44aa9d5bade97baf + (0,17) | 17 | 7.358 | 70efdf2ec9b086079795c442636b55fb + (0,18) | 18 | 1.535 | 6f4922f45568161a8cdf4ad2299f6d23 + (0,19) | 19 | 5.218 | 1f0e3dad99908345f7439f8ffabdffc4 + (0,20) | 20 | 7.869 | 98f13708210194c475687be6106a3b84 + (0,21) | 21 | 1.498 | 3c59dc048e8850243be8079a5c74d079 + (0,22) | 22 | 1.717 | b6d767d2f8ed5d21a44b0e5886680cb9 + (0,23) | 23 | 9.137 | 37693cfc748049e45d87b8c7d8b9aacd + (0,24) | 24 | 6.755 | 1ff1de774005f8da13f42943881c655f + (0,25) | 25 | 7.485 | 8e296a067a37563370ded05f5a3bf3ec + (0,26) | 26 | 3.362 | 4e732ced3463d06de0ca9a15b6153677 + (0,27) | 27 | 9.81 | 02e74f10e0327ad868d138f2b4fdd6f0 + (0,28) | 28 | 0.117 | 33e75ff09dd601bbe69f351039152189 + (0,29) | 29 | 5.164 | 6ea9ab1baa0efb9e19094440c317e21b + (0,30) | 30 | 1.124 | 34173cb38f07f89ddbebc2ac9128303f + (0,31) | 31 | 3.356 | c16a5320fa475530d9583c34fd356ef5 + (0,32) | 32 | 7.89 | 6364d3f0f495b6ab9dcf8d3b5c6e0b01 + (0,33) | 33 | 9.026 | 182be0c5cdcd5072bb1864cdee4d3d6e + (0,34) | 34 | 2.454 | e369853df766fa44e1ed0ff613f563bd + (0,35) | 35 | 8.377 | 1c383cd30b7c298ab50293adfecb7b18 + (0,36) | 36 | 3.822 | 19ca14e7ea6328a42e0eb13d585e4c22 + (0,37) | 37 | 4.284 | a5bfc9e07964f8dddeb95fc584cd965d + (0,38) | 38 | 4.004 | a5771bce93e200c36f7cd9dfd0e5deaa + (0,39) | 39 | 2.237 | d67d8ab4f4c10bf22aa353e27879133c + (0,40) | 40 | 9.594 | d645920e395fedad7bbbed0eca3fe2e0 + (0,41) | 41 | 5.435 | 3416a75f4cea9109507cacd8e2f2aefc + (0,42) | 42 | 1.668 | a1d0c6e83f027327d8461063f4ac58a6 + (0,43) | 43 | 6.172 | 17e62166fc8586dfa4d1bc0e1742c08b + (0,44) | 44 | 6.43 | f7177163c833dff4b38fc8d2872f1ec6 + (0,45) | 45 | 4.28 | 6c8349cc7260ae62e3b1396831a8398f + (0,46) | 46 | 4.601 | d9d4f495e875a2e075a1a4a6e1b9770f + (0,47) | 47 | 9.07 | 67c6a1e7ce56d3d6fa748ab6d9af3fd7 + (0,48) | 48 | 1.638 | 642e92efb79421734881b53e1e1b18b6 + (0,49) | 49 | 6.136 | f457c545a9ded88f18ecee47145a72c0 + (0,50) | 50 | 4.288 | c0c7c76d30bd3dcaefc96f40275bdc0a + (0,51) | 51 | 9.506 | 2838023a778dfaecdc212708f721b788 + (0,52) | 52 | 7.633 | 9a1158154dfa42caddbd0694a4e9bdc8 + (0,53) | 53 | 6.005 | d82c8d1619ad8176d665453cfb2e55f0 + (0,54) | 54 | 8.643 | a684eceee76fc522773286a895bc8436 + (0,55) | 55 | 4.387 | b53b3a3d6ab90ce0268229151c9bde11 + (0,56) | 56 | 3.489 | 9f61408e3afb633e50cdf1b20de6f466 + (0,57) | 57 | 2.005 | 72b32a1f754ba1c09b3695e0cb6cde7f + (0,58) | 58 | 4.196 | 66f041e16a60928b05a7e228a89c3799 + (0,59) | 59 | 3.606 | 093f65e080a295f8076b1c5722a46aa2 + (0,60) | 60 | 7.168 | 072b030ba126b2f4b2374f342be9ed44 + (0,61) | 61 | 5.32 | 7f39f8317fbdb1988ef4c628eba02591 + (0,62) | 62 | 6.961 | 44f683a84163b3523afe57c2e008bc8c + (0,63) | 63 | 5.058 | 03afdbd66e7929b125f8597834fa83a4 + (0,64) | 64 | 4.345 | ea5d2f1c4608232e07d3aa3d998e5135 + (0,65) | 65 | 9.415 | fc490ca45c00b1249bbe3554a4fdf6fb + (0,66) | 66 | 3.435 | 3295c76acbf4caaed33c36b1b5fc2cb1 + (0,67) | 67 | 8.166 | 735b90b4568125ed6c3f678819b6e058 + (0,68) | 68 | 3.698 | a3f390d88e4c41f2747bfa2f1b5f87db + (0,69) | 69 | 7.438 | 14bfa6bb14875e45bba028a21ed38046 + (0,70) | 70 | 0.403 | 7cbbc409ec990f19c78c75bd1e06f215 + (0,71) | 71 | 3.292 | e2c420d928d4bf8ce0ff2ec19b371514 + (0,72) | 72 | 2.873 | 32bb90e8976aab5298d5da10fe66f21d + (0,73) | 73 | 2.07 | d2ddea18f00665ce8623e36bd4e3c7c5 + (0,74) | 74 | 9.463 | ad61ab143223efbc24c7d2583be69251 + (0,75) | 75 | 9.303 | d09bf41544a3365a46c9077ebb5e35c3 + (0,76) | 76 | 6.35 | fbd7939d674997cdb4692d34de8633c4 + (0,77) | 77 | 4.064 | 28dd2c7955ce926456240b2ff0100bde + (0,78) | 78 | 8.373 | 35f4a8d465e6e1edc05f3d8ab658c551 + (0,79) | 79 | 7.987 | d1fe173d08e959397adf34b1d77e88d7 + (0,80) | 80 | 0.199 | f033ab37c30201f73f142449d037028d + (0,81) | 81 | 2.66 | 43ec517d68b6edd3015b3edc9a11367b + (0,82) | 82 | 7.493 | 9778d5d219c5080b9a6a17bef029331c + (0,83) | 83 | 7.831 | fe9fc289c3ff0af142b6d3bead98a923 + (0,84) | 84 | 8.664 | 68d30a9594728bc39aa24be94b319d21 + (0,85) | 85 | 6.136 | 3ef815416f775098fe977004015c6193 + (0,86) | 86 | 2.218 | 93db85ed909c13838ff95ccfa94cebd9 + (0,87) | 87 | 2.152 | c7e1249ffc03eb9ded908c236bd1996d + (0,88) | 88 | 8.14 | 2a38a4a9316c49e5a833517c45d31070 + (0,89) | 89 | 6.414 | 7647966b7343c29048673252e490f736 + (0,90) | 90 | 5.757 | 8613985ec49eb8f757ae6439e879bb2a + (0,91) | 91 | 5.307 | 54229abfcfa5649e7003b83dd4755294 + (0,92) | 92 | 1.733 | 92cc227532d17e56e07902b254dfad10 + (0,93) | 93 | 2.718 | 98dce83da57b0395e163467c9dae521b + (0,94) | 94 | 0.365 | f4b9ec30ad9f68f89b29639786cb62ef + (0,95) | 95 | 6.077 | 812b4ba287f5ee0bc9d43bbf5bbe87fb + (0,96) | 96 | 2.132 | 26657d5ff9020d2abefe558796b99584 + (0,97) | 97 | 3.799 | e2ef524fbf3d9fe611d5a8e90fefdc9c + (1,1) | 98 | 4.243 | ed3d2c21991e3bef5e069713af9fa6ca + (1,2) | 99 | 5.83 | ac627ab1ccbdb62ec96e702f07f6425b + (1,3) | 100 | 1.237 | f899139df5e1059396431415e770c6dd + (1,4) | 101 | 4.645 | 38b3eff8baf56627478ec76a704e9b52 + (1,5) | 102 | 9.121 | ec8956637a99787bd197eacd77acce5e + (1,6) | 103 | 4.109 | 6974ce5ac660610b44d9b9fed0ff9548 + (1,7) | 104 | 6.715 | c9e1074f5b3f9fc8ea15d152add07294 + (1,8) | 105 | 8.583 | 65b9eea6e1cc6bb9f0cd2a47751a186f + (1,9) | 106 | 3.412 | f0935e4cd5920aa6c7c996a5ee53a70f + (1,10) | 107 | 3.065 | a97da629b098b75c294dffdc3e463904 + (1,11) | 108 | 2.646 | a3c65c2974270fd093ee8a9bf8ae7d0b + (1,12) | 109 | 1.784 | 2723d092b63885e0d7c260cc007e8b9d + (1,13) | 110 | 1.052 | 5f93f983524def3dca464469d2cf9f3e + (1,14) | 111 | 2.845 | 698d51a19d8a121ce581499d7b701668 + (1,15) | 112 | 4.443 | 7f6ffaa6bb0b408017b62254211691b5 + (1,16) | 113 | 8.544 | 73278a4a86960eeb576a8fd4c9ec6997 + (1,17) | 114 | 0.675 | 5fd0b37cd7dbbb00f97ba6ce92bf5add + (1,18) | 115 | 3.107 | 2b44928ae11fb9384c4cf38708677c48 + (1,19) | 116 | 4.68 | c45147dee729311ef5b5c3003946c48f + (1,20) | 117 | 2.893 | eb160de1de89d9058fcb0b968dbbbd68 +(117 rows) + +SELECT ctid,* FROM t1 WHERE ctid > '(10,0)'::tid; + ctid | a | b | c +---------+------+-------+---------------------------------- + (10,1) | 971 | 3.963 | 6602294be910b1e3c4571bd98c4d5484 + (10,2) | 972 | 7.836 | c22abfa379f38b5b0411bc11fa9bf92f + (10,3) | 973 | 2.017 | ca75910166da03ff9d4655a0338e6b09 + (10,4) | 974 | 3.717 | 4311359ed4969e8401880e3c1836fbe1 + (10,5) | 975 | 6.5 | 92977ae4d2ba21425a59afb269c2a14e + (10,6) | 976 | 2.317 | 9c01802ddb981e6bcfbec0f0516b8e35 + (10,7) | 977 | 0.112 | cc1aa436277138f61cda703991069eaf + (10,8) | 978 | 8.832 | 2ab56412b1163ee131e1246da0955bd1 + (10,9) | 979 | 4.022 | c32d9bf27a3da7ec8163957080c8628e + (10,10) | 980 | 6.216 | d79aac075930c83c2f1e369a511148fe + (10,11) | 981 | 2.501 | 287e03db1d99e0ec2edb90d079e142f3 + (10,12) | 982 | 1.32 | fec8d47d412bcbeece3d9128ae855a7a + (10,13) | 983 | 7.567 | 6aab1270668d8cac7cef2566a1c5f569 + (10,14) | 984 | 7.962 | d93ed5b6db83be78efb0d05ae420158e + (10,15) | 985 | 6.823 | 54a367d629152b720749e187b3eaa11b + (10,16) | 986 | 5.97 | fe7ee8fc1959cc7214fa21c4840dff0a + (10,17) | 987 | 1.539 | df6d2338b2b8fce1ec2f6dda0a630eb0 + (10,18) | 988 | 5.619 | 9908279ebbf1f9b250ba689db6a0222b + (10,19) | 989 | 7.603 | a1140a3d0df1c81e24ae954d935e8926 + (10,20) | 990 | 8.716 | 4fac9ba115140ac4f1c22da82aa0bc7f + (10,21) | 991 | 2.868 | 692f93be8c7a41525c0baf2076aecfb4 + (10,22) | 992 | 7.804 | 860320be12a1c050cd7731794e231bd3 + (10,23) | 993 | 9.428 | 7b13b2203029ed80337f27127a9f1d28 + (10,24) | 994 | 7.015 | 934815ad542a4a7c5e8a2dfa04fea9f5 + (10,25) | 995 | 2.438 | 2bcab9d935d219641434683dd9d18a03 + (10,26) | 996 | 7.22 | 0b8aff0438617c055eb55f0ba5d226fa + (10,27) | 997 | 5.012 | ec5aa0b7846082a2415f0902f0da88f2 + (10,28) | 998 | 2.945 | 9ab0d88431732957a618d4a469a0d4c3 + (10,29) | 999 | 2.569 | b706835de79a2b4e80506f582af3676a + (10,30) | 1000 | 2.776 | a9b7ba70783b617e9998dc4dd82eb3c5 +(30 rows) + +SELECT ctid,* FROM t1 WHERE c like '%678%' AND ctid >= '(3,50)'::tid; + ctid | a | b | c +--------+-----+-------+---------------------------------- + (6,78) | 660 | 2.946 | 68264bdb65b97eeae6788aa3348e553c + (7,43) | 722 | 1.612 | c8ed21db4f678f3b13b9d5ee16489088 + (8,36) | 812 | 3.673 | 81e74d678581a3bb7a720b019f4f1a93 + (9,97) | 970 | 7.977 | 89fcd07f20b6785b92134bd6c1d0fa42 +(4 rows) + +SELECT ctid,* FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; + ctid | a | b | c +--------+-----+-------+---------------------------------- + (3,1) | 292 | 3.11 | 1700002963a49da13542e0726b7bb758 + (3,2) | 293 | 4.932 | 53c3bce66e43be4f209556518c2fcb54 + (3,3) | 294 | 3.851 | 6883966fd8f918a4aa29be29d2c386fb + (3,4) | 295 | 9.821 | 49182f81e6a13cf5eaa496d51fea6406 + (3,5) | 296 | 1.623 | d296c101daa88a51f6ca8cfc1ac79b50 + (3,6) | 297 | 9.248 | 9fd81843ad7f202f26c1a174c7357585 + (3,7) | 298 | 8.073 | 26e359e83860db1d11b6acca57d8ea88 + (3,8) | 299 | 5.224 | ef0d3930a7b6c95bd2b32ed45989c61f + (3,9) | 300 | 4.252 | 94f6d7e04a4d452035300f18b984988c + (3,10) | 301 | 4.599 | 34ed066df378efacc9b924ec161e7639 +(10 rows) + +SELECT t1.ctid,* FROM t1 NATURAL JOIN t3 WHERE t3.ctid IN ( + SELECT t3.ctid FROM t2 NATURAL JOIN t3 + WHERE t2.ctid BETWEEN '(4,0)'::tid AND '(5,0)'::tid); + ctid | a | b | c | x +---------+------+-------+----------------------------------+----- + (5,43) | 528 | 6.581 | f4be00279ee2e0a53eafdaa94a151e2c | 646 + (4,67) | 455 | 4.602 | 821fa74b50ba3f7cba1e6c53e8fa6845 | 682 + (4,96) | 484 | 5.29 | eba0dc302bcd9a273f8bbb72be3a687b | 632 + (3,82) | 373 | 4.013 | ffd52f3c7e12435a724a8f30fddadd9c | 647 + (0,95) | 95 | 6.077 | 812b4ba287f5ee0bc9d43bbf5bbe87fb | 625 + (2,48) | 242 | 5.099 | e4a6222cdb5b34375400904f03d8e6a5 | 600 + (0,79) | 79 | 7.987 | d1fe173d08e959397adf34b1d77e88d7 | 685 + (9,91) | 964 | 4.635 | 8065d07da4a77621450aa84fee5656d9 | 659 + (4,68) | 456 | 7.784 | 250cf8b51c773f3f8dc8b4be867a9a02 | 606 + (3,7) | 298 | 8.073 | 26e359e83860db1d11b6acca57d8ea88 | 630 + (3,95) | 386 | 8.354 | 39461a19e9eddfb385ea76b26521ea48 | 653 + (4,36) | 424 | 2.163 | 3c7781a36bcd6cf08c11a970fbe0e2a6 | 682 + (3,53) | 344 | 6.972 | b3967a0e938dc2a6340e258630febd5a | 598 + (5,90) | 575 | 5.791 | ffeabd223de0d4eacb9a3e6e53e5448d | 647 + (5,70) | 555 | 7.829 | 15de21c670ae7c3f6f3f1f37029303c9 | 675 + (8,39) | 815 | 9.544 | 71ad16ad2c4d81f348082ff6c4b20768 | 679 + (2,81) | 275 | 0.633 | 63923f49e5241343aa7acb6a06a751e7 | 665 + (9,79) | 952 | 1.352 | e6cb2a3c14431b55aa50c06529eaa21b | 674 + (2,71) | 265 | 6.691 | e56954b4f6347e897f954495eab16a88 | 645 + (2,78) | 272 | 7.8 | 7a614fd06c325499f1680b9896beedeb | 676 + (8,92) | 868 | 9.159 | dd45045f8c68db9f54e70c67048d32e8 | 660 + (5,61) | 546 | 8.622 | ed265bc903a5a097f61d3ec064d96d2e | 677 + (6,53) | 635 | 1.307 | 6a10bbd480e4c5573d8f3af73ae0454b | 678 + (7,7) | 686 | 9.864 | 109a0ca3bc27f3e96597370d5c8cf03d | 675 + (0,30) | 30 | 1.124 | 34173cb38f07f89ddbebc2ac9128303f | 684 + (2,80) | 274 | 3.661 | d947bf06a885db0d477d707121934ff8 | 660 + (9,57) | 930 | 8.568 | 1cc3633c579a90cfdd895e64021e2163 | 676 + (5,59) | 544 | 1.784 | 97e8527feaf77a97fc38f34216141515 | 628 + (5,34) | 519 | 8.643 | 63538fe6ef330c13a05a3ed7e599d5f7 | 644 + (0,41) | 41 | 5.435 | 3416a75f4cea9109507cacd8e2f2aefc | 616 + (6,9) | 591 | 4.95 | 3493894fa4ea036cfc6433c3e2ee63b0 | 624 + (5,68) | 553 | 3.933 | f387624df552cea2f369918c5e1e12bc | 656 + (6,13) | 595 | 4.497 | 04ecb1fa28506ccb6f72b12c0245ddbc | 640 + (5,92) | 577 | 0.858 | fde9264cf376fffe2ee4ddf4a988880d | 595 + (8,96) | 872 | 3.613 | 43feaeeecd7b2fe2ae2e26d917b6477d | 675 + (0,14) | 14 | 2.613 | aab3238922bcc25a6f606eb525ffdc56 | 627 + (6,13) | 595 | 4.497 | 04ecb1fa28506ccb6f72b12c0245ddbc | 675 + (7,44) | 723 | 7.51 | 08419be897405321542838d77f855226 | 601 + (7,12) | 691 | 1.983 | 10a5ab2db37feedfdeaab192ead4ac0e | 633 + (9,66) | 939 | 7.47 | 3df1d4b96d8976ff5986393e8767f5b2 | 601 + (5,65) | 550 | 1.335 | 01f78be6f7cad02658508fe4616098a9 | 674 + (10,13) | 983 | 7.567 | 6aab1270668d8cac7cef2566a1c5f569 | 640 + (4,69) | 457 | 6.687 | 42998cf32d552343bc8e460416382dca | 655 + (6,46) | 628 | 4.6 | 42e77b63637ab381e8be5f8318cc28a2 | 596 + (9,95) | 968 | 5.349 | 8f468c873a32bb0619eaeb2050ba45d1 | 634 + (6,36) | 618 | 4.784 | eb6fdc36b281b7d5eabf33396c2683a2 | 597 + (1,92) | 189 | 3.371 | a2557a7b2e94197ff767970b67041697 | 645 + (10,23) | 993 | 9.428 | 7b13b2203029ed80337f27127a9f1d28 | 670 + (7,62) | 741 | 9.252 | 2e65f2f2fdaf6c699b223c61b1b5ab89 | 609 + (0,8) | 8 | 8.416 | c9f0f895fb98ab9159f51fd0297e236d | 636 + (8,33) | 809 | 6.587 | 32b30a250abd6331e03a2a1f16466346 | 624 + (9,76) | 949 | 6.105 | 3cef96dcc9b8035d23f69e30bb19218a | 656 + (9,50) | 923 | 8.205 | c4015b7f368e6b4871809f49debe0579 | 685 + (7,11) | 690 | 1.344 | c06d06da9666a219db15cf575aff2824 | 664 + (9,68) | 941 | 0.072 | 92262bf907af914b95a0fc33c3f33bf6 | 638 + (3,46) | 337 | 3.233 | 357a6fdf7642bf815a88822c447d9dc4 | 657 + (1,53) | 150 | 2.874 | 7ef605fc8dba5425d6965fbd4c8fbe1f | 684 + (0,24) | 24 | 6.755 | 1ff1de774005f8da13f42943881c655f | 626 + (8,76) | 852 | 4.716 | 22ac3c5a5bf0b520d281c122d1490650 | 593 + (2,91) | 285 | 1.867 | 0e01938fc48a2cfb5f2217fbfb00722d | 603 + (0,68) | 68 | 3.698 | a3f390d88e4c41f2747bfa2f1b5f87db | 659 + (5,89) | 574 | 2.237 | f0e52b27a7a5d6a1a87373dffa53dbe5 | 657 + (8,6) | 782 | 0.276 | 72da7fd6d1302c0a159f6436d01e9eb0 | 625 + (9,89) | 962 | 0.712 | 5c936263f3428a40227908d5a3847c0b | 660 + (3,44) | 335 | 5.056 | f9b902fc3289af4dd08de5d1de54f68f | 600 + (7,86) | 765 | 2.005 | d840cc5d906c3e9c84374c8919d2074e | 679 + (7,28) | 707 | 9.357 | 500e75a036dc2d7d2fec5da1b71d36cc | 624 + (1,90) | 187 | 7.392 | 31fefc0e570cb3860f2a6d4b38c6490d | 604 + (9,60) | 933 | 4.434 | 043c3d7e489c69b48737cc0c92d0f3a2 | 658 + (8,40) | 816 | 0.334 | 43fa7f58b7eac7ac872209342e62e8f1 | 613 + (3,66) | 357 | 7.196 | fb7b9ffa5462084c5f4e7e85a093e6d7 | 675 + (2,6) | 200 | 9.843 | 3644a684f98ea8fe223c713b77189a77 | 630 + (5,29) | 514 | 2 | 59b90e1005a220e2ebc542eb9d950b1e | 662 + (0,35) | 35 | 8.377 | 1c383cd30b7c298ab50293adfecb7b18 | 617 + (5,8) | 493 | 9.349 | 2f55707d4193dc27118a0f19a1985716 | 678 + (9,76) | 949 | 6.105 | 3cef96dcc9b8035d23f69e30bb19218a | 613 + (7,58) | 737 | 0.95 | a5cdd4aa0048b187f7182f1b9ce7a6a7 | 671 + (3,28) | 319 | 7.195 | 8d3bba7425e7c98c50f52ca1b52d3735 | 627 + (0,85) | 85 | 6.136 | 3ef815416f775098fe977004015c6193 | 598 + (9,26) | 899 | 5.338 | 01882513d5fa7c329e940dda99b12147 | 623 + (2,45) | 239 | 8.274 | 555d6702c950ecb729a966504af0a635 | 609 + (4,34) | 422 | 1.542 | f85454e8279be180185cac7d243c5eb3 | 618 + (2,36) | 230 | 1.073 | 6da9003b743b65f4c0ccd295cc484e57 | 646 + (8,46) | 822 | 5.911 | afda332245e2af431fb7b672a68b659d | 668 + (9,53) | 926 | 3.294 | cbb6a3b884f4f88b3a8e3d44c636cbd8 | 611 + (8,13) | 789 | 3.511 | 68053af2923e00204c3ca7c6a3150cf7 | 668 + (3,60) | 351 | 4.695 | efe937780e95574250dabe07151bdc23 | 596 + (9,56) | 929 | 8.454 | 0d0871f0806eae32d30983b62252da50 | 620 + (8,48) | 824 | 0.742 | 677e09724f0e2df9b6c000b75b5da10d | 679 + (0,21) | 21 | 1.498 | 3c59dc048e8850243be8079a5c74d079 | 607 + (2,36) | 230 | 1.073 | 6da9003b743b65f4c0ccd295cc484e57 | 658 + (3,12) | 303 | 2.051 | 11b9842e0a271ff252c1903e7132cd68 | 640 + (8,38) | 814 | 5.229 | 96b9bff013acedfb1d140579e2fbeb63 | 659 + (10,28) | 998 | 2.945 | 9ab0d88431732957a618d4a469a0d4c3 | 619 + (7,81) | 760 | 4.54 | 2ca65f58e35d9ad45bf7f3ae5cfd08f1 | 671 + (0,5) | 5 | 4.796 | e4da3b7fbbce2345d7772b0674a318d5 | 593 + (6,81) | 663 | 2.433 | 8757150decbd89b0f5442ca3db4d0e0e | 646 + (3,2) | 293 | 4.932 | 53c3bce66e43be4f209556518c2fcb54 | 682 + (7,69) | 748 | 0.086 | e49b8b4053df9505e1f48c3a701c0682 | 617 + (3,47) | 338 | 1.571 | 819f46e52c25763a55cc642422644317 | 617 + (8,71) | 847 | 3.652 | f4552671f8909587cf485ea990207f3b | 637 + (1,40) | 137 | 1.045 | 3988c7f88ebcb58c6ce932b957b6f332 | 600 + (8,56) | 832 | 3.089 | 7250eb93b3c18cc9daa29cf58af7a004 | 606 + (0,50) | 50 | 4.288 | c0c7c76d30bd3dcaefc96f40275bdc0a | 601 + (8,25) | 801 | 2.903 | 1905aedab9bf2477edc068a355bba31a | 642 + (0,87) | 87 | 2.152 | c7e1249ffc03eb9ded908c236bd1996d | 631 + (8,61) | 837 | 4.784 | b0b183c207f46f0cca7dc63b2604f5cc | 669 + (0,73) | 73 | 2.07 | d2ddea18f00665ce8623e36bd4e3c7c5 | 663 + (9,61) | 934 | 7.081 | 4daa3db355ef2b0e64b472968cb70f0d | 684 + (3,79) | 370 | 8.387 | d709f38ef758b5066ef31b18039b8ce5 | 674 + (10,4) | 974 | 3.717 | 4311359ed4969e8401880e3c1836fbe1 | 670 + (5,83) | 568 | 8.956 | dd458505749b2941217ddd59394240e8 | 683 + (9,50) | 923 | 8.205 | c4015b7f368e6b4871809f49debe0579 | 663 + (8,79) | 855 | 5.458 | addfa9b7e234254d26e9c7f2af1005cb | 628 + (1,41) | 138 | 5.781 | 013d407166ec4fa56eb1e1f8cbe183b9 | 669 + (7,3) | 682 | 8.117 | 08d98638c6fcd194a4b1e6992063e944 | 610 + (10,3) | 973 | 2.017 | ca75910166da03ff9d4655a0338e6b09 | 640 + (9,58) | 931 | 3.535 | 9f53d83ec0691550f7d2507d57f4f5a2 | 634 + (1,42) | 139 | 2.042 | e00da03b685a0dd18fb6a08af0923de0 | 618 + (3,16) | 307 | 6.515 | 8e98d81f8217304975ccb23337bb5761 | 631 + (3,9) | 300 | 4.252 | 94f6d7e04a4d452035300f18b984988c | 653 + (3,86) | 377 | 9.915 | d34ab169b70c9dcd35e62896010cd9ff | 599 + (8,37) | 813 | 4.154 | e0cf1f47118daebc5b16269099ad7347 | 627 + (3,29) | 320 | 3.232 | 320722549d1751cf3f247855f937b982 | 657 + (6,31) | 613 | 9.934 | f29c21d4897f78948b91f03172341b7b | 640 + (9,51) | 924 | 7.052 | bea5955b308361a1b07bc55042e25e54 | 649 + (2,38) | 232 | 2.033 | be83ab3ecd0db773eb2dc1b0a17836a1 | 659 + (7,84) | 763 | 6.188 | eefc9e10ebdc4a2333b42b2dbb8f27b6 | 669 + (6,91) | 673 | 2.212 | 9f396fe44e7c05c16873b05ec425cbad | 596 + (1,17) | 114 | 0.675 | 5fd0b37cd7dbbb00f97ba6ce92bf5add | 673 + (7,58) | 737 | 0.95 | a5cdd4aa0048b187f7182f1b9ce7a6a7 | 635 + (10,30) | 1000 | 2.776 | a9b7ba70783b617e9998dc4dd82eb3c5 | 674 + (9,40) | 913 | 8.593 | 8b5040a8a5baf3e0e67386c2e3a9b903 | 654 + (0,35) | 35 | 8.377 | 1c383cd30b7c298ab50293adfecb7b18 | 597 + (2,48) | 242 | 5.099 | e4a6222cdb5b34375400904f03d8e6a5 | 671 + (5,75) | 560 | 6.777 | a9a6653e48976138166de32772b1bf40 | 623 + (1,23) | 120 | 9.306 | da4fb5c6e93e74d3df8527599fa62642 | 637 + (6,90) | 672 | 0.675 | 2dea61eed4bceec564a00115c4d21334 | 608 + (4,42) | 430 | 4.709 | f74909ace68e51891440e4da0b65a70c | 667 + (10,1) | 971 | 3.963 | 6602294be910b1e3c4571bd98c4d5484 | 683 + (2,57) | 251 | 3.423 | 19f3cd308f1455b3fa09a282e0d496f4 | 641 + (2,66) | 260 | 7.864 | a4f23670e1833f3fdb077ca70bbd5d66 | 677 + (7,32) | 711 | 1.699 | 6081594975a764c8e3a691fa2b3a321d | 682 + (8,2) | 778 | 9.912 | e07413354875be01a996dc560274708e | 607 + (7,89) | 768 | 2.954 | 3a835d3215755c435ef4fe9965a3f2a0 | 644 + (9,50) | 923 | 8.205 | c4015b7f368e6b4871809f49debe0579 | 625 + (6,31) | 613 | 9.934 | f29c21d4897f78948b91f03172341b7b | 633 + (8,95) | 871 | 0.53 | aeb3135b436aa55373822c010763dd54 | 636 + (0,64) | 64 | 4.345 | ea5d2f1c4608232e07d3aa3d998e5135 | 652 + (8,82) | 858 | 9.043 | a67f096809415ca1c9f112d96d27689b | 660 + (4,42) | 430 | 4.709 | f74909ace68e51891440e4da0b65a70c | 657 + (4,84) | 472 | 2.045 | ef575e8837d065a1683c022d2077d342 | 672 + (4,79) | 467 | 7.696 | ab817c9349cf9c4f6877e1894a1faa00 | 612 + (4,63) | 451 | 9.186 | 941e1aaaba585b952b62c14a3a175a61 | 618 + (2,71) | 265 | 6.691 | e56954b4f6347e897f954495eab16a88 | 653 + (7,12) | 691 | 1.983 | 10a5ab2db37feedfdeaab192ead4ac0e | 598 + (6,4) | 586 | 0.092 | 605ff764c617d3cd28dbbdd72be8f9a2 | 661 + (1,28) | 125 | 8.49 | 3def184ad8f4755ff269862ea77393dd | 637 + (2,94) | 288 | 6.092 | 48aedb8880cab8c45637abc7493ecddd | 676 + (8,40) | 816 | 0.334 | 43fa7f58b7eac7ac872209342e62e8f1 | 605 + (0,38) | 38 | 4.004 | a5771bce93e200c36f7cd9dfd0e5deaa | 662 + (2,16) | 210 | 3.191 | 6f3ef77ac0e3619e98159e9b6febf557 | 645 + (3,51) | 342 | 5.627 | 58238e9ae2dd305d79c2ebc8c1883422 | 635 + (0,64) | 64 | 4.345 | ea5d2f1c4608232e07d3aa3d998e5135 | 644 + (2,31) | 225 | 8.138 | d1c38a09acc34845c6be3a127a5aacaf | 630 + (0,65) | 65 | 9.415 | fc490ca45c00b1249bbe3554a4fdf6fb | 612 + (6,37) | 619 | 0.825 | cdc0d6e63aa8e41c89689f54970bb35f | 638 + (0,6) | 6 | 1.83 | 1679091c5a880faf6fb5e6087eb1b2dc | 661 + (1,13) | 110 | 1.052 | 5f93f983524def3dca464469d2cf9f3e | 608 + (3,74) | 365 | 4.71 | 9be40cee5b0eee1462c82c6964087ff9 | 591 + (5,47) | 532 | 1.293 | 298f95e1bf9136124592c8d4825a06fc | 649 + (0,39) | 39 | 2.237 | d67d8ab4f4c10bf22aa353e27879133c | 676 + (2,69) | 263 | 9.896 | 8c19f571e251e61cb8dd3612f26d5ecf | 652 + (8,33) | 809 | 6.587 | 32b30a250abd6331e03a2a1f16466346 | 608 + (8,47) | 823 | 2.887 | 632cee946db83e7a52ce5e8d6f0fed35 | 592 + (8,62) | 838 | 5.287 | f9028faec74be6ec9b852b0a542e2f39 | 620 + (2,12) | 206 | 2.416 | 7eabe3a1649ffa2b3ff8c02ebfd5659f | 627 + (0,10) | 10 | 1.431 | d3d9446802a44259755d38e6d163e820 | 655 + (7,15) | 694 | 4.415 | 5487315b1286f907165907aa8fc96619 | 600 + (0,39) | 39 | 2.237 | d67d8ab4f4c10bf22aa353e27879133c | 646 + (7,63) | 742 | 8.773 | e94550c93cd70fe748e6982b3439ad3b | 624 + (8,57) | 833 | 4.053 | 013a006f03dbc5392effeb8f18fda755 | 670 + (6,34) | 616 | 2.651 | 7750ca3559e5b8e1f44210283368fc16 | 617 + (4,74) | 462 | 3.655 | 51d92be1c60d1db1d2e5e7a07da55b26 | 606 + (7,46) | 725 | 6.027 | 82f2b308c3b01637c607ce05f52a2fed | 684 + (0,88) | 88 | 8.14 | 2a38a4a9316c49e5a833517c45d31070 | 594 + (3,73) | 364 | 5.908 | bac9162b47c56fc8a4d2a519803d51b3 | 646 + (2,48) | 242 | 5.099 | e4a6222cdb5b34375400904f03d8e6a5 | 637 + (2,30) | 224 | 2.281 | 13fe9d84310e77f13a6d184dbf1232f3 | 615 + (6,18) | 600 | 7.89 | d490d7b4576290fa60eb31b5fc917ad1 | 612 + (7,32) | 711 | 1.699 | 6081594975a764c8e3a691fa2b3a321d | 651 + (10,15) | 985 | 6.823 | 54a367d629152b720749e187b3eaa11b | 609 + (7,65) | 744 | 6.956 | 0537fb40a68c18da59a35c2bfe1ca554 | 605 + (6,22) | 604 | 1.82 | 9cf81d8026a9018052c429cc4e56739b | 608 + (0,26) | 26 | 3.362 | 4e732ced3463d06de0ca9a15b6153677 | 649 + (3,89) | 380 | 5.038 | bca82e41ee7b0833588399b1fcd177c7 | 631 + (7,39) | 718 | 1.134 | 50c3d7614917b24303ee6a220679dab3 | 668 + (0,30) | 30 | 1.124 | 34173cb38f07f89ddbebc2ac9128303f | 669 + (7,51) | 730 | 7.128 | d5cfead94f5350c12c322b5b664544c1 | 592 + (5,56) | 541 | 1.924 | 16c222aa19898e5058938167c8ab6c57 | 605 + (8,20) | 796 | 2.844 | 35cf8659cfcb13224cbd47863a34fc58 | 600 + (0,22) | 22 | 1.717 | b6d767d2f8ed5d21a44b0e5886680cb9 | 654 + (2,78) | 272 | 7.8 | 7a614fd06c325499f1680b9896beedeb | 643 + (8,23) | 799 | 5.797 | 28267ab848bcf807b2ed53c3a8f8fc8a | 658 + (10,11) | 981 | 2.501 | 287e03db1d99e0ec2edb90d079e142f3 | 615 + (2,75) | 269 | 5.004 | 06138bc5af6023646ede0e1f7c1eac75 | 642 + (2,57) | 251 | 3.423 | 19f3cd308f1455b3fa09a282e0d496f4 | 616 + (1,22) | 119 | 2.819 | 07e1cd7dca89a1678042477183b7ac3f | 607 + (9,8) | 881 | 0.085 | 7504adad8bb96320eb3afdd4df6e1f60 | 607 + (3,27) | 318 | 9.977 | 432aca3a1e345e339f35a30c8f65edce | 648 + (9,23) | 896 | 6.179 | 061412e4a03c02f9902576ec55ebbe77 | 652 + (0,55) | 55 | 4.387 | b53b3a3d6ab90ce0268229151c9bde11 | 641 + (9,45) | 918 | 9.71 | 1e056d2b0ebd5c878c550da6ac5d3724 | 601 + (5,90) | 575 | 5.791 | ffeabd223de0d4eacb9a3e6e53e5448d | 612 + (8,55) | 831 | 3.798 | e0ec453e28e061cc58ac43f91dc2f3f0 | 637 + (0,31) | 31 | 3.356 | c16a5320fa475530d9583c34fd356ef5 | 609 + (6,3) | 585 | 2.718 | a9a1d5317a33ae8cef33961c34144f84 | 613 + (2,47) | 241 | 2.797 | f340f1b1f65b6df5b5e3f94d95b11daf | 671 + (5,88) | 573 | 9.128 | e5f6ad6ce374177eef023bf5d0c018b6 | 628 + (0,95) | 95 | 6.077 | 812b4ba287f5ee0bc9d43bbf5bbe87fb | 625 + (3,22) | 313 | 9.237 | 158f3069a435b314a80bdcb024f8e422 | 636 + (5,4) | 489 | 5.183 | 854d9fca60b4bd07f9bb215d59ef5561 | 596 + (5,54) | 539 | 6.363 | 5737034557ef5b8c02c0e46513b98f90 | 657 + (6,12) | 594 | 3.02 | 076a0c97d09cf1a0ec3e19c7f2529f2b | 647 + (2,72) | 266 | 5.398 | f7664060cc52bc6f3d620bcedc94a4b6 | 602 + (7,24) | 703 | 8.668 | d6c651ddcd97183b2e40bc464231c962 | 621 + (3,81) | 372 | 4.623 | 24b16fede9a67c9251d3e7c7161c83ac | 615 + (0,35) | 35 | 8.377 | 1c383cd30b7c298ab50293adfecb7b18 | 644 + (2,24) | 218 | 8.642 | e96ed478dab8595a7dbda4cbcbee168f | 604 + (0,8) | 8 | 8.416 | c9f0f895fb98ab9159f51fd0297e236d | 671 + (3,21) | 312 | 6.709 | 950a4152c2b4aa3ad78bdd6b366cc179 | 643 + (8,49) | 825 | 2.157 | d554f7bb7be44a7267068a7df88ddd20 | 676 + (3,49) | 340 | 5.059 | 40008b9a5380fcacce3976bf7c08af5b | 653 + (6,56) | 638 | 6.102 | 4c27cea8526af8cfee3be5e183ac9605 | 617 + (4,37) | 425 | 5.531 | 25b2822c2f5a3230abfadd476e8b04c9 | 621 + (0,43) | 43 | 6.172 | 17e62166fc8586dfa4d1bc0e1742c08b | 634 + (8,47) | 823 | 2.887 | 632cee946db83e7a52ce5e8d6f0fed35 | 619 + (6,89) | 671 | 0.604 | 5dd9db5e033da9c6fb5ba83c7a7ebea9 | 639 + (4,92) | 480 | 4.075 | 6ea2ef7311b482724a9b7b0bc0dd85c6 | 620 + (3,92) | 383 | 2.874 | beed13602b9b0e6ecb5b568ff5058f07 | 633 + (2,95) | 289 | 5.666 | 839ab46820b524afda05122893c2fe8e | 629 + (7,62) | 741 | 9.252 | 2e65f2f2fdaf6c699b223c61b1b5ab89 | 654 + (2,45) | 239 | 8.274 | 555d6702c950ecb729a966504af0a635 | 629 + (4,72) | 460 | 6.222 | 98b297950041a42470269d56260243a1 | 672 + (6,32) | 614 | 0.956 | 851ddf5058cf22df63d3344ad89919cf | 677 + (2,77) | 271 | 6.958 | 7f100b7b36092fb9b06dfb4fac360931 | 679 + (8,60) | 836 | 7.597 | ab88b15733f543179858600245108dd8 | 643 + (7,4) | 683 | 4.026 | 24681928425f5a9133504de568f5f6df | 639 + (4,21) | 409 | 2.081 | a96b65a721e561e1e3de768ac819ffbb | 649 + (1,86) | 183 | 6.743 | cedebb6e872f539bef8c3f919874e9d7 | 605 + (7,35) | 714 | 5.725 | d14220ee66aeec73c49038385428ec4c | 618 + (4,37) | 425 | 5.531 | 25b2822c2f5a3230abfadd476e8b04c9 | 656 + (8,8) | 784 | 5.872 | fc8001f834f6a5f0561080d134d53d29 | 669 + (2,73) | 267 | 8.253 | eda80a3d5b344bc40f3bc04f65b7a357 | 615 + (8,75) | 851 | 3.901 | 92fb0c6d1758261f10d052e6e2c1123c | 607 + (0,45) | 45 | 4.28 | 6c8349cc7260ae62e3b1396831a8398f | 670 + (2,50) | 244 | 2.833 | 9188905e74c28e489b44e954ec0b9bca | 637 + (6,18) | 600 | 7.89 | d490d7b4576290fa60eb31b5fc917ad1 | 664 + (0,55) | 55 | 4.387 | b53b3a3d6ab90ce0268229151c9bde11 | 607 + (3,34) | 325 | 4.999 | 89f0fd5c927d466d6ec9a21b9ac34ffa | 641 + (8,52) | 828 | 4.898 | c2626d850c80ea07e7511bbae4c76f4b | 622 + (7,93) | 772 | 5.411 | e57c6b956a6521b28495f2886ca0977a | 685 + (8,19) | 795 | 2.923 | 7c590f01490190db0ed02a5070e20f01 | 671 + (0,84) | 84 | 8.664 | 68d30a9594728bc39aa24be94b319d21 | 604 + (3,26) | 317 | 7.566 | 5b8add2a5d98b1a652ea7fd72d942dac | 604 + (8,3) | 779 | 1.881 | 67d96d458abdef21792e6d8e590244e7 | 636 + (5,52) | 537 | 2.986 | 5ea1649a31336092c05438df996a3e59 | 655 + (0,73) | 73 | 2.07 | d2ddea18f00665ce8623e36bd4e3c7c5 | 595 + (5,59) | 544 | 1.784 | 97e8527feaf77a97fc38f34216141515 | 645 + (2,92) | 286 | 9.295 | 16a5cdae362b8d27a1d8f8c7b78b4330 | 614 + (7,6) | 685 | 2.887 | 3328bdf9a4b9504b9398284244fe97c2 | 594 + (5,41) | 526 | 7.94 | 85422afb467e9456013a2a51d4dff702 | 606 + (0,29) | 29 | 5.164 | 6ea9ab1baa0efb9e19094440c317e21b | 640 + (6,92) | 674 | 4.837 | 0d7de1aca9299fe63f3e0041f02638a3 | 632 + (2,87) | 281 | 4.883 | e3796ae838835da0b6f6ea37bcf8bcb7 | 652 + (6,70) | 652 | 6.461 | 30ef30b64204a3088a26bc2e6ecf7602 | 609 + (2,74) | 268 | 3.602 | 8f121ce07d74717e0b1f21d122e04521 | 631 + (8,25) | 801 | 2.903 | 1905aedab9bf2477edc068a355bba31a | 636 + (5,85) | 570 | 7.279 | a86c450b76fb8c371afead6410d55534 | 653 + (5,30) | 515 | 6.417 | 2b8a61594b1f4c4db0902a8a395ced93 | 647 + (2,33) | 227 | 9.687 | 705f2172834666788607efbfca35afb3 | 666 + (4,88) | 476 | 1.154 | 598b3e71ec378bd83e0a727608b5db01 | 649 + (8,85) | 861 | 8.424 | f9a40a4780f5e1306c46f1c8daecee3b | 637 + (9,75) | 948 | 1.705 | 58e4d44e550d0f7ee0a23d6b02d9b0db | 605 + (9,13) | 886 | 5.146 | 704afe073992cbe4813cae2f7715336f | 638 + (3,60) | 351 | 4.695 | efe937780e95574250dabe07151bdc23 | 607 + (2,62) | 256 | 9.927 | f718499c1c8cef6730f9fd03c8125cab | 675 + (10,6) | 976 | 2.317 | 9c01802ddb981e6bcfbec0f0516b8e35 | 664 + (7,55) | 734 | 0.84 | e995f98d56967d946471af29d7bf99f1 | 598 + (5,78) | 563 | 8.07 | 8eefcfdf5990e441f0fb6f3fad709e21 | 656 + (8,51) | 827 | 3.585 | fa3a3c407f82377f55c19c5d403335c7 | 643 + (6,56) | 638 | 6.102 | 4c27cea8526af8cfee3be5e183ac9605 | 658 + (2,67) | 261 | 7.444 | b1a59b315fc9a3002ce38bbe070ec3f5 | 653 + (7,59) | 738 | 9.665 | 217eedd1ba8c592db97d0dbe54c7adfc | 604 + (3,13) | 304 | 6.224 | 37bc2f75bf1bcfe8450a1a41c200364c | 648 + (9,2) | 875 | 6.93 | 4b0a59ddf11c58e7446c9df0da541a84 | 597 + (4,87) | 475 | 9.427 | 5ef0b4eba35ab2d6180b0bca7e46b6f9 | 645 + (4,94) | 482 | 7.234 | f770b62bc8f42a0b66751fe636fc6eb0 | 643 + (6,55) | 637 | 2.075 | a532400ed62e772b9dc0b86f46e583ff | 615 + (2,86) | 280 | 8.207 | 92c8c96e4c37100777c7190b76d28233 | 614 + (3,6) | 297 | 9.248 | 9fd81843ad7f202f26c1a174c7357585 | 594 + (0,58) | 58 | 4.196 | 66f041e16a60928b05a7e228a89c3799 | 609 + (8,8) | 784 | 5.872 | fc8001f834f6a5f0561080d134d53d29 | 602 + (8,12) | 788 | 5.519 | c15da1f2b5e5ed6e6837a3802f0d1593 | 649 + (10,4) | 974 | 3.717 | 4311359ed4969e8401880e3c1836fbe1 | 667 + (9,54) | 927 | 3.231 | 1f4477bad7af3616c1f933a02bfabe4e | 597 + (4,13) | 401 | 5.05 | 816b112c6105b3ebd537828a39af4818 | 631 + (9,45) | 918 | 9.71 | 1e056d2b0ebd5c878c550da6ac5d3724 | 655 + (2,14) | 208 | 6.732 | 091d584fced301b442654dd8c23b3fc9 | 592 + (4,90) | 478 | 2.325 | cfee398643cbc3dc5eefc89334cacdc1 | 616 + (0,29) | 29 | 5.164 | 6ea9ab1baa0efb9e19094440c317e21b | 632 + (4,59) | 447 | 2.898 | 9a96876e2f8f3dc4f3cf45f02c61c0c1 | 629 + (1,64) | 161 | 7.939 | bd4c9ab730f5513206b999ec0d90d1fb | 668 + (5,9) | 494 | 4.764 | 1be3bc32e6564055d5ca3e5a354acbef | 601 + (6,73) | 655 | 5.838 | 3d2d8ccb37df977cb6d9da15b76c3f3a | 626 + (9,10) | 883 | 9.689 | 210f760a89db30aa72ca258a3483cc7f | 602 + (8,97) | 873 | 8.51 | 98d6f58ab0dafbb86b083a001561bb34 | 657 + (6,95) | 677 | 8.81 | 71a3cb155f8dc89bf3d0365288219936 | 608 + (0,14) | 14 | 2.613 | aab3238922bcc25a6f606eb525ffdc56 | 669 + (8,38) | 814 | 5.229 | 96b9bff013acedfb1d140579e2fbeb63 | 611 + (2,23) | 217 | 0.693 | 63dc7ed1010d3c3b8269faf0ba7491d4 | 620 + (8,62) | 838 | 5.287 | f9028faec74be6ec9b852b0a542e2f39 | 615 + (3,48) | 339 | 9.967 | 04025959b191f8f9de3f924f0940515f | 619 + (7,13) | 692 | 9.199 | e555ebe0ce426f7f9b2bef0706315e0c | 593 + (3,73) | 364 | 5.908 | bac9162b47c56fc8a4d2a519803d51b3 | 604 + (4,16) | 404 | 9.063 | 4f4adcbf8c6f66dcfc8a3282ac2bf10a | 611 + (7,47) | 726 | 3.435 | 0d3180d672e08b4c5312dcdafdf6ef36 | 589 + (6,76) | 658 | 2.859 | 2f37d10131f2a483a8dd005b3d14b0d9 | 657 + (9,72) | 945 | 0.3 | 4b6538a44a1dfdc2b83477cd76dee98e | 652 + (4,70) | 458 | 4.067 | d07e70efcfab08731a97e7b91be644de | 648 + (6,87) | 669 | 9.84 | 5c04925674920eb58467fb52ce4ef728 | 673 + (6,64) | 646 | 3.973 | 0ff39bbbf981ac0151d340c9aa40e63e | 655 + (0,78) | 78 | 8.373 | 35f4a8d465e6e1edc05f3d8ab658c551 | 670 + (8,56) | 832 | 3.089 | 7250eb93b3c18cc9daa29cf58af7a004 | 666 + (8,60) | 836 | 7.597 | ab88b15733f543179858600245108dd8 | 669 + (6,15) | 597 | 5.807 | 08c5433a60135c32e34f46a71175850c | 622 + (1,64) | 161 | 7.939 | bd4c9ab730f5513206b999ec0d90d1fb | 592 + (4,6) | 394 | 3.99 | 28f0b864598a1291557bed248a998d4e | 664 + (5,38) | 523 | 2.255 | 2bb232c0b13c774965ef8558f0fbd615 | 653 + (2,50) | 244 | 2.833 | 9188905e74c28e489b44e954ec0b9bca | 630 + (3,34) | 325 | 4.999 | 89f0fd5c927d466d6ec9a21b9ac34ffa | 614 + (3,95) | 386 | 8.354 | 39461a19e9eddfb385ea76b26521ea48 | 594 + (0,38) | 38 | 4.004 | a5771bce93e200c36f7cd9dfd0e5deaa | 601 + (5,27) | 512 | 1.128 | 10a7cdd970fe135cf4f7bb55c0e3b59f | 657 + (6,73) | 655 | 5.838 | 3d2d8ccb37df977cb6d9da15b76c3f3a | 628 + (3,85) | 376 | 7.911 | 142949df56ea8ae0be8b5306971900a4 | 646 + (10,6) | 976 | 2.317 | 9c01802ddb981e6bcfbec0f0516b8e35 | 654 + (7,36) | 715 | 3.201 | 8df707a948fac1b4a0f97aa554886ec8 | 595 + (6,48) | 630 | 3.619 | 9cc138f8dc04cbf16240daa92d8d50e2 | 657 + (1,40) | 137 | 1.045 | 3988c7f88ebcb58c6ce932b957b6f332 | 629 + (5,91) | 576 | 2.975 | a7aeed74714116f3b292a982238f83d2 | 661 + (7,39) | 718 | 1.134 | 50c3d7614917b24303ee6a220679dab3 | 623 + (6,62) | 644 | 0.769 | 8c7bbbba95c1025975e548cee86dfadc | 674 + (8,75) | 851 | 3.901 | 92fb0c6d1758261f10d052e6e2c1123c | 664 + (3,89) | 380 | 5.038 | bca82e41ee7b0833588399b1fcd177c7 | 685 + (0,97) | 97 | 3.799 | e2ef524fbf3d9fe611d5a8e90fefdc9c | 621 + (8,90) | 866 | 9.162 | ca8155f4d27f205953f9d3d7974bdd70 | 678 + (8,38) | 814 | 5.229 | 96b9bff013acedfb1d140579e2fbeb63 | 613 + (3,35) | 326 | 6.161 | a666587afda6e89aec274a3657558a27 | 676 + (3,86) | 377 | 9.915 | d34ab169b70c9dcd35e62896010cd9ff | 644 + (5,46) | 531 | 0.877 | 0fcbc61acd0479dc77e3cccc0f5ffca7 | 599 + (2,22) | 216 | 5.678 | 45fbc6d3e05ebd93369ce542e8f2322d | 591 + (7,62) | 741 | 9.252 | 2e65f2f2fdaf6c699b223c61b1b5ab89 | 657 + (7,73) | 752 | 6.81 | a1d33d0dfec820b41b54430b50e96b5c | 660 + (8,41) | 817 | 4.968 | 31839b036f63806cba3f47b93af8ccb5 | 678 + (1,58) | 155 | 0.382 | 2a79ea27c279e471f4d180b08d62b00a | 679 + (3,10) | 301 | 4.599 | 34ed066df378efacc9b924ec161e7639 | 606 + (4,40) | 428 | 4.838 | 8d7d8ee069cb0cbbf816bbb65d56947e | 602 + (6,50) | 632 | 9.487 | abd815286ba1007abfbb8415b83ae2cf | 641 + (4,67) | 455 | 4.602 | 821fa74b50ba3f7cba1e6c53e8fa6845 | 665 + (5,62) | 547 | 2.692 | c75b6f114c23a4d7ea11331e7c00e73c | 640 + (6,7) | 589 | 7.307 | 30bb3825e8f631cc6075c0f87bb4978c | 665 + (2,38) | 232 | 2.033 | be83ab3ecd0db773eb2dc1b0a17836a1 | 607 + (0,34) | 34 | 2.454 | e369853df766fa44e1ed0ff613f563bd | 639 + (8,22) | 798 | 4.377 | 9e3cfc48eccf81a0d57663e129aef3cb | 601 + (9,48) | 921 | 5.248 | 430c3626b879b4005d41b8a46172e0c0 | 615 + (8,60) | 836 | 7.597 | ab88b15733f543179858600245108dd8 | 658 + (2,31) | 225 | 8.138 | d1c38a09acc34845c6be3a127a5aacaf | 633 + (0,56) | 56 | 3.489 | 9f61408e3afb633e50cdf1b20de6f466 | 651 + (0,18) | 18 | 1.535 | 6f4922f45568161a8cdf4ad2299f6d23 | 643 + (3,20) | 311 | 5.661 | 9dfcd5e558dfa04aaf37f137a1d9d3e5 | 682 + (6,35) | 617 | 1.047 | 5d44ee6f2c3f71b73125876103c8f6c4 | 621 + (2,80) | 274 | 3.661 | d947bf06a885db0d477d707121934ff8 | 647 + (5,68) | 553 | 3.933 | f387624df552cea2f369918c5e1e12bc | 623 + (3,97) | 388 | 2.299 | d9fc5b73a8d78fad3d6dffe419384e70 | 672 + (7,38) | 717 | 5.589 | 788d986905533aba051261497ecffcbb | 669 + (5,67) | 552 | 3.296 | 94c7bb58efc3b337800875b5d382a072 | 642 + (8,56) | 832 | 3.089 | 7250eb93b3c18cc9daa29cf58af7a004 | 612 + (0,25) | 25 | 7.485 | 8e296a067a37563370ded05f5a3bf3ec | 659 + (10,12) | 982 | 1.32 | fec8d47d412bcbeece3d9128ae855a7a | 642 + (7,74) | 753 | 8.786 | 6f2268bd1d3d3ebaabb04d6b5d099425 | 631 + (0,45) | 45 | 4.28 | 6c8349cc7260ae62e3b1396831a8398f | 612 + (0,84) | 84 | 8.664 | 68d30a9594728bc39aa24be94b319d21 | 600 + (3,97) | 388 | 2.299 | d9fc5b73a8d78fad3d6dffe419384e70 | 593 + (3,75) | 366 | 5.318 | 5ef698cd9fe650923ea331c15af3b160 | 667 + (1,59) | 156 | 9.49 | 1c9ac0159c94d8d0cbedc973445af2da | 601 + (5,10) | 495 | 5.686 | 35051070e572e47d2c26c241ab88307f | 662 + (4,25) | 413 | 0.414 | 0deb1c54814305ca9ad266f53bc82511 | 675 + (3,26) | 317 | 7.566 | 5b8add2a5d98b1a652ea7fd72d942dac | 654 + (1,24) | 121 | 1.015 | 4c56ff4ce4aaf9573aa5dff913df997a | 630 + (7,91) | 770 | 8.527 | 4ea06fbc83cdd0a06020c35d50e1e89a | 681 + (7,50) | 729 | 5.201 | 5751ec3e9a4feab575962e78e006250d | 685 + (8,21) | 797 | 2.742 | beb22fb694d513edcf5533cf006dfeae | 648 + (4,26) | 414 | 0.84 | 66808e327dc79d135ba18e051673d906 | 612 + (0,23) | 23 | 9.137 | 37693cfc748049e45d87b8c7d8b9aacd | 628 + (2,19) | 213 | 0.037 | 979d472a84804b9f647bc185a877a8b5 | 683 + (7,34) | 713 | 7.704 | 07c5807d0d927dcd0980f86024e5208b | 608 + (2,59) | 253 | 1.789 | c24cd76e1ce41366a4bbe8a49b02a028 | 602 + (6,21) | 603 | 1.898 | d86ea612dec96096c5e0fcc8dd42ab6d | 603 + (9,79) | 952 | 1.352 | e6cb2a3c14431b55aa50c06529eaa21b | 594 + (3,70) | 361 | 9.237 | 52720e003547c70561bf5e03b95aa99f | 654 + (6,19) | 601 | 2.693 | b2f627fff19fda463cb386442eac2b3d | 616 + (5,49) | 534 | 7.218 | c399862d3b9d6b76c8436e924a68c45b | 601 + (9,55) | 928 | 3.601 | d045c59a90d7587d8d671b5f5aec4e7c | 613 + (1,77) | 174 | 4.08 | bf8229696f7a3bb4700cfddef19fa23f | 644 + (1,28) | 125 | 8.49 | 3def184ad8f4755ff269862ea77393dd | 659 + (7,84) | 763 | 6.188 | eefc9e10ebdc4a2333b42b2dbb8f27b6 | 601 + (2,35) | 229 | 3.638 | 57aeee35c98205091e18d1140e9f38cf | 598 + (6,20) | 602 | 6.631 | c3992e9a68c5ae12bd18488bc579b30d | 643 + (5,5) | 490 | 5.695 | c410003ef13d451727aeff9082c29a5c | 627 + (3,96) | 387 | 2.769 | 8efb100a295c0c690931222ff4467bb8 | 641 + (4,50) | 438 | 0.622 | 1651cf0d2f737d7adeab84d339dbabd3 | 601 + (9,91) | 964 | 4.635 | 8065d07da4a77621450aa84fee5656d9 | 654 + (1,44) | 141 | 6.832 | 0f28b5d49b3020afeecd95b4009adf4c | 594 + (6,81) | 663 | 2.433 | 8757150decbd89b0f5442ca3db4d0e0e | 637 + (4,14) | 402 | 8.246 | 69cb3ea317a32c4e6143e665fdb20b14 | 598 + (8,68) | 844 | 3.318 | e97ee2054defb209c35fe4dc94599061 | 589 + (3,66) | 357 | 7.196 | fb7b9ffa5462084c5f4e7e85a093e6d7 | 626 + (9,55) | 928 | 3.601 | d045c59a90d7587d8d671b5f5aec4e7c | 606 + (9,34) | 907 | 5.918 | 621461af90cadfdaf0e8d4cc25129f91 | 675 + (8,21) | 797 | 2.742 | beb22fb694d513edcf5533cf006dfeae | 683 + (6,88) | 670 | 4.681 | 17c276c8e723eb46aef576537e9d56d0 | 624 + (3,27) | 318 | 9.977 | 432aca3a1e345e339f35a30c8f65edce | 667 + (1,72) | 169 | 1.767 | 3636638817772e42b59d74cff571fbb3 | 668 + (0,36) | 36 | 3.822 | 19ca14e7ea6328a42e0eb13d585e4c22 | 593 + (9,85) | 958 | 1.634 | d240e3d38a8882ecad8633c8f9c78c9b | 631 + (6,2) | 584 | 3.751 | f5deaeeae1538fb6c45901d524ee2f98 | 641 + (7,88) | 767 | 1.454 | f2201f5191c4e92cc5af043eebfd0946 | 595 + (0,97) | 97 | 3.799 | e2ef524fbf3d9fe611d5a8e90fefdc9c | 592 + (3,64) | 355 | 5.48 | 82cec96096d4281b7c95cd7e74623496 | 617 + (4,14) | 402 | 8.246 | 69cb3ea317a32c4e6143e665fdb20b14 | 609 + (5,41) | 526 | 7.94 | 85422afb467e9456013a2a51d4dff702 | 598 + (8,24) | 800 | 8.901 | 7a53928fa4dd31e82c6ef826f341daec | 644 + (6,67) | 649 | 8.757 | 55b37c5c270e5d84c793e486d798c01d | 592 + (8,13) | 789 | 3.511 | 68053af2923e00204c3ca7c6a3150cf7 | 665 + (1,57) | 154 | 8.796 | 1d7f7abc18fcb43975065399b0d1e48e | 682 + (8,45) | 821 | 9.903 | 4558dbb6f6f8bb2e16d03b85bde76e2c | 672 + (6,87) | 669 | 9.84 | 5c04925674920eb58467fb52ce4ef728 | 685 + (6,79) | 661 | 6.478 | 3a066bda8c96b9478bb0512f0a43028c | 663 + (7,57) | 736 | 2.94 | 6bc24fc1ab650b25b4114e93a98f1eba | 604 + (1,42) | 139 | 2.042 | e00da03b685a0dd18fb6a08af0923de0 | 685 + (7,68) | 747 | 7.546 | 8d317bdcf4aafcfc22149d77babee96d | 622 + (3,28) | 319 | 7.195 | 8d3bba7425e7c98c50f52ca1b52d3735 | 626 + (0,78) | 78 | 8.373 | 35f4a8d465e6e1edc05f3d8ab658c551 | 667 + (2,52) | 246 | 7.953 | 38db3aed920cf82ab059bfccbd02be6a | 672 + (5,92) | 577 | 0.858 | fde9264cf376fffe2ee4ddf4a988880d | 631 + (4,85) | 473 | 3.453 | 2050e03ca119580f74cca14cc6e97462 | 658 + (8,6) | 782 | 0.276 | 72da7fd6d1302c0a159f6436d01e9eb0 | 632 + (7,19) | 698 | 1.767 | 99bcfcd754a98ce89cb86f73acc04645 | 682 + (9,53) | 926 | 3.294 | cbb6a3b884f4f88b3a8e3d44c636cbd8 | 593 + (3,57) | 348 | 1.463 | 01386bd6d8e091c2ab4c7c7de644d37b | 613 + (3,38) | 329 | 4.234 | 6faa8040da20ef399b63a72d0e4ab575 | 683 + (8,37) | 813 | 4.154 | e0cf1f47118daebc5b16269099ad7347 | 607 + (1,25) | 122 | 8.126 | a0a080f42e6f13b3a2df133f073095dd | 602 + (6,67) | 649 | 8.757 | 55b37c5c270e5d84c793e486d798c01d | 671 + (9,97) | 970 | 7.977 | 89fcd07f20b6785b92134bd6c1d0fa42 | 624 + (2,35) | 229 | 3.638 | 57aeee35c98205091e18d1140e9f38cf | 613 + (8,73) | 849 | 4.814 | fe8c15fed5f808006ce95eddb7366e35 | 669 + (6,50) | 632 | 9.487 | abd815286ba1007abfbb8415b83ae2cf | 639 + (10,30) | 1000 | 2.776 | a9b7ba70783b617e9998dc4dd82eb3c5 | 669 + (2,31) | 225 | 8.138 | d1c38a09acc34845c6be3a127a5aacaf | 667 + (5,42) | 527 | 9.387 | 13f320e7b5ead1024ac95c3b208610db | 669 + (1,3) | 100 | 1.237 | f899139df5e1059396431415e770c6dd | 604 + (6,35) | 617 | 1.047 | 5d44ee6f2c3f71b73125876103c8f6c4 | 662 + (8,8) | 784 | 5.872 | fc8001f834f6a5f0561080d134d53d29 | 678 + (1,7) | 104 | 6.715 | c9e1074f5b3f9fc8ea15d152add07294 | 633 + (2,71) | 265 | 6.691 | e56954b4f6347e897f954495eab16a88 | 651 + (5,21) | 506 | 5.768 | ff4d5fbbafdf976cfdc032e3bde78de5 | 640 + (1,41) | 138 | 5.781 | 013d407166ec4fa56eb1e1f8cbe183b9 | 673 + (1,29) | 126 | 7.115 | 069059b7ef840f0c74a814ec9237b6ec | 650 + (1,72) | 169 | 1.767 | 3636638817772e42b59d74cff571fbb3 | 608 + (5,17) | 502 | 0.735 | b5b41fac0361d157d9673ecb926af5ae | 655 + (1,87) | 184 | 7.903 | 6cdd60ea0045eb7a6ec44c54d29ed402 | 681 + (3,57) | 348 | 1.463 | 01386bd6d8e091c2ab4c7c7de644d37b | 644 + (1,35) | 132 | 6.002 | 65ded5353c5ee48d0b7d48c591b8f430 | 640 + (0,70) | 70 | 0.403 | 7cbbc409ec990f19c78c75bd1e06f215 | 623 + (10,5) | 975 | 6.5 | 92977ae4d2ba21425a59afb269c2a14e | 663 + (8,78) | 854 | 6.787 | f7e9050c92a851b0016442ab604b0488 | 658 + (8,54) | 830 | 9.382 | 8e82ab7243b7c66d768f1b8ce1c967eb | 647 + (5,23) | 508 | 1.412 | 389bc7bb1e1c2a5e7e147703232a88f6 | 596 + (3,4) | 295 | 9.821 | 49182f81e6a13cf5eaa496d51fea6406 | 632 + (7,24) | 703 | 8.668 | d6c651ddcd97183b2e40bc464231c962 | 628 + (2,53) | 247 | 8.511 | 3cec07e9ba5f5bb252d13f5f431e4bbb | 595 + (2,7) | 201 | 8.395 | 757b505cfd34c64c85ca5b5690ee5293 | 626 + (3,66) | 357 | 7.196 | fb7b9ffa5462084c5f4e7e85a093e6d7 | 643 + (8,7) | 783 | 3.212 | 6e0721b2c6977135b916ef286bcb49ec | 615 + (6,71) | 653 | 0.018 | eaae339c4d89fc102edd9dbdb6a28915 | 650 + (7,54) | 733 | 7.616 | 6c29793a140a811d0c45ce03c1c93a28 | 661 + (0,91) | 91 | 5.307 | 54229abfcfa5649e7003b83dd4755294 | 666 + (4,55) | 443 | 3.362 | 13f3cf8c531952d72e5847c4183e6910 | 646 + (1,87) | 184 | 7.903 | 6cdd60ea0045eb7a6ec44c54d29ed402 | 634 + (0,19) | 19 | 5.218 | 1f0e3dad99908345f7439f8ffabdffc4 | 656 + (6,61) | 643 | 4.234 | 9b698eb3105bd82528f23d0c92dedfc0 | 679 + (0,4) | 4 | 0.488 | a87ff679a2f3e71d9181a67b7542122c | 594 + (4,89) | 477 | 1.205 | 74071a673307ca7459bcf75fbd024e09 | 594 + (3,94) | 385 | 5.103 | dc912a253d1e9ba40e2c597ed2376640 | 620 + (1,55) | 152 | 6.651 | 37a749d808e46495a8da1e5352d03cae | 602 + (0,57) | 57 | 2.005 | 72b32a1f754ba1c09b3695e0cb6cde7f | 616 + (8,23) | 799 | 5.797 | 28267ab848bcf807b2ed53c3a8f8fc8a | 669 + (4,68) | 456 | 7.784 | 250cf8b51c773f3f8dc8b4be867a9a02 | 684 + (4,89) | 477 | 1.205 | 74071a673307ca7459bcf75fbd024e09 | 681 + (6,25) | 607 | 4.795 | dc82d632c9fcecb0778afbc7924494a6 | 673 + (7,55) | 734 | 0.84 | e995f98d56967d946471af29d7bf99f1 | 674 + (2,59) | 253 | 1.789 | c24cd76e1ce41366a4bbe8a49b02a028 | 674 + (6,22) | 604 | 1.82 | 9cf81d8026a9018052c429cc4e56739b | 610 + (0,40) | 40 | 9.594 | d645920e395fedad7bbbed0eca3fe2e0 | 601 + (2,83) | 277 | 1.613 | 20f07591c6fcb220ffe637cda29bb3f6 | 665 + (10,13) | 983 | 7.567 | 6aab1270668d8cac7cef2566a1c5f569 | 593 + (4,50) | 438 | 0.622 | 1651cf0d2f737d7adeab84d339dbabd3 | 591 + (8,55) | 831 | 3.798 | e0ec453e28e061cc58ac43f91dc2f3f0 | 645 + (7,82) | 761 | 0.899 | 88ae6372cfdc5df69a976e893f4d554b | 607 + (10,8) | 978 | 8.832 | 2ab56412b1163ee131e1246da0955bd1 | 616 + (6,19) | 601 | 2.693 | b2f627fff19fda463cb386442eac2b3d | 657 + (2,36) | 230 | 1.073 | 6da9003b743b65f4c0ccd295cc484e57 | 616 + (8,47) | 823 | 2.887 | 632cee946db83e7a52ce5e8d6f0fed35 | 683 + (1,10) | 107 | 3.065 | a97da629b098b75c294dffdc3e463904 | 638 + (9,10) | 883 | 9.689 | 210f760a89db30aa72ca258a3483cc7f | 589 + (1,71) | 168 | 3.981 | 006f52e9102a8d3be2fe5614f42ba989 | 645 + (0,23) | 23 | 9.137 | 37693cfc748049e45d87b8c7d8b9aacd | 684 + (2,19) | 213 | 0.037 | 979d472a84804b9f647bc185a877a8b5 | 647 + (5,77) | 562 | 8.753 | 4e4b5fbbbb602b6d35bea8460aa8f8e5 | 608 + (5,42) | 527 | 9.387 | 13f320e7b5ead1024ac95c3b208610db | 625 + (7,77) | 756 | 4.813 | 2823f4797102ce1a1aec05359cc16dd9 | 673 + (10,23) | 993 | 9.428 | 7b13b2203029ed80337f27127a9f1d28 | 663 + (4,20) | 408 | 2.929 | 0d0fd7c6e093f7b804fa0150b875b868 | 650 + (6,52) | 634 | 4.386 | 6766aa2750c19aad2fa1b32f36ed4aee | 677 + (6,19) | 601 | 2.693 | b2f627fff19fda463cb386442eac2b3d | 644 + (4,59) | 447 | 2.898 | 9a96876e2f8f3dc4f3cf45f02c61c0c1 | 605 + (5,96) | 581 | 9.818 | c6e19e830859f2cb9f7c8f8cacb8d2a6 | 682 + (7,59) | 738 | 9.665 | 217eedd1ba8c592db97d0dbe54c7adfc | 617 + (10,12) | 982 | 1.32 | fec8d47d412bcbeece3d9128ae855a7a | 662 + (1,6) | 103 | 4.109 | 6974ce5ac660610b44d9b9fed0ff9548 | 596 + (2,41) | 235 | 5.502 | 577ef1154f3240ad5b9b413aa7346a1e | 610 + (4,79) | 467 | 7.696 | ab817c9349cf9c4f6877e1894a1faa00 | 597 + (10,21) | 991 | 2.868 | 692f93be8c7a41525c0baf2076aecfb4 | 599 + (9,72) | 945 | 0.3 | 4b6538a44a1dfdc2b83477cd76dee98e | 657 + (7,53) | 732 | 1.649 | ba3866600c3540f67c1e9575e213be0a | 665 + (5,10) | 495 | 5.686 | 35051070e572e47d2c26c241ab88307f | 649 + (3,32) | 323 | 6.341 | bc6dc48b743dc5d013b1abaebd2faed2 | 611 + (1,40) | 137 | 1.045 | 3988c7f88ebcb58c6ce932b957b6f332 | 621 + (5,42) | 527 | 9.387 | 13f320e7b5ead1024ac95c3b208610db | 641 + (1,55) | 152 | 6.651 | 37a749d808e46495a8da1e5352d03cae | 620 + (4,75) | 463 | 0.808 | 428fca9bc1921c25c5121f9da7815cde | 668 + (3,16) | 307 | 6.515 | 8e98d81f8217304975ccb23337bb5761 | 640 + (9,20) | 893 | 1.805 | d56b9fc4b0f1be8871f5e1c40c0067e7 | 681 + (1,51) | 148 | 8.453 | 47d1e990583c9c67424d369f3414728e | 599 + (10,1) | 971 | 3.963 | 6602294be910b1e3c4571bd98c4d5484 | 632 + (1,76) | 173 | 5.075 | f7e6c85504ce6e82442c770f7c8606f0 | 679 + (1,29) | 126 | 7.115 | 069059b7ef840f0c74a814ec9237b6ec | 631 + (9,87) | 960 | 7.25 | 437d7d1d97917cd627a34a6a0fb41136 | 662 + (0,82) | 82 | 7.493 | 9778d5d219c5080b9a6a17bef029331c | 635 + (6,25) | 607 | 4.795 | dc82d632c9fcecb0778afbc7924494a6 | 591 + (0,4) | 4 | 0.488 | a87ff679a2f3e71d9181a67b7542122c | 612 + (4,36) | 424 | 2.163 | 3c7781a36bcd6cf08c11a970fbe0e2a6 | 594 + (9,16) | 889 | 4.188 | 07871915a8107172b3b5dc15a6574ad3 | 623 + (6,70) | 652 | 6.461 | 30ef30b64204a3088a26bc2e6ecf7602 | 683 + (5,86) | 571 | 0.032 | c9892a989183de32e976c6f04e700201 | 672 + (1,61) | 158 | 6.246 | 06409663226af2f3114485aa4e0a23b4 | 677 + (9,62) | 935 | 3.85 | e820a45f1dfc7b95282d10b6087e11c0 | 608 + (5,70) | 555 | 7.829 | 15de21c670ae7c3f6f3f1f37029303c9 | 645 + (4,24) | 412 | 7.018 | b9228e0962a78b84f3d5d92f4faa000b | 674 + (2,92) | 286 | 9.295 | 16a5cdae362b8d27a1d8f8c7b78b4330 | 680 + (8,73) | 849 | 4.814 | fe8c15fed5f808006ce95eddb7366e35 | 662 + (9,84) | 957 | 8.796 | 2ba596643cbbbc20318224181fa46b28 | 671 + (4,26) | 414 | 0.84 | 66808e327dc79d135ba18e051673d906 | 647 + (10,19) | 989 | 7.603 | a1140a3d0df1c81e24ae954d935e8926 | 591 + (7,20) | 699 | 9.884 | afd4836712c5e77550897e25711e1d96 | 605 + (7,94) | 773 | 7.299 | 86b122d4358357d834a87ce618a55de0 | 646 + (10,18) | 988 | 5.619 | 9908279ebbf1f9b250ba689db6a0222b | 598 + (0,96) | 96 | 2.132 | 26657d5ff9020d2abefe558796b99584 | 678 + (8,18) | 794 | 6.246 | 82489c9737cc245530c7a6ebef3753ec | 683 + (5,59) | 544 | 1.784 | 97e8527feaf77a97fc38f34216141515 | 603 + (8,25) | 801 | 2.903 | 1905aedab9bf2477edc068a355bba31a | 607 + (4,42) | 430 | 4.709 | f74909ace68e51891440e4da0b65a70c | 675 + (6,51) | 633 | 0.25 | 26dd0dbc6e3f4c8043749885523d6a25 | 662 + (3,51) | 342 | 5.627 | 58238e9ae2dd305d79c2ebc8c1883422 | 622 + (3,82) | 373 | 4.013 | ffd52f3c7e12435a724a8f30fddadd9c | 660 + (3,26) | 317 | 7.566 | 5b8add2a5d98b1a652ea7fd72d942dac | 623 + (2,20) | 214 | 3.568 | ca46c1b9512a7a8315fa3c5a946e8265 | 650 + (3,83) | 374 | 4.769 | ad972f10e0800b49d76fed33a21f6698 | 629 + (10,22) | 992 | 7.804 | 860320be12a1c050cd7731794e231bd3 | 679 + (0,17) | 17 | 7.358 | 70efdf2ec9b086079795c442636b55fb | 680 + (6,13) | 595 | 4.497 | 04ecb1fa28506ccb6f72b12c0245ddbc | 632 + (4,6) | 394 | 3.99 | 28f0b864598a1291557bed248a998d4e | 596 + (0,88) | 88 | 8.14 | 2a38a4a9316c49e5a833517c45d31070 | 670 + (0,16) | 16 | 2.64 | c74d97b01eae257e44aa9d5bade97baf | 683 + (2,30) | 224 | 2.281 | 13fe9d84310e77f13a6d184dbf1232f3 | 664 + (1,64) | 161 | 7.939 | bd4c9ab730f5513206b999ec0d90d1fb | 641 + (6,2) | 584 | 3.751 | f5deaeeae1538fb6c45901d524ee2f98 | 674 + (10,3) | 973 | 2.017 | ca75910166da03ff9d4655a0338e6b09 | 676 + (7,2) | 681 | 9.106 | 1595af6435015c77a7149e92a551338e | 601 + (5,83) | 568 | 8.956 | dd458505749b2941217ddd59394240e8 | 621 + (0,48) | 48 | 1.638 | 642e92efb79421734881b53e1e1b18b6 | 611 + (5,61) | 546 | 8.622 | ed265bc903a5a097f61d3ec064d96d2e | 651 + (5,31) | 516 | 0.909 | f3f27a324736617f20abbf2ffd806f6d | 651 + (3,44) | 335 | 5.056 | f9b902fc3289af4dd08de5d1de54f68f | 661 + (1,26) | 123 | 1.038 | 202cb962ac59075b964b07152d234b70 | 590 + (1,47) | 144 | 5.376 | 0a09c8844ba8f0936c20bd791130d6b6 | 663 + (10,23) | 993 | 9.428 | 7b13b2203029ed80337f27127a9f1d28 | 675 + (1,34) | 131 | 3.525 | 1afa34a7f984eeabdbb0a7d494132ee5 | 593 + (3,48) | 339 | 9.967 | 04025959b191f8f9de3f924f0940515f | 660 + (4,21) | 409 | 2.081 | a96b65a721e561e1e3de768ac819ffbb | 681 + (4,6) | 394 | 3.99 | 28f0b864598a1291557bed248a998d4e | 589 + (1,32) | 129 | 1.358 | d1f491a404d6854880943e5c3cd9ca25 | 610 + (2,5) | 199 | 1.387 | 84d9ee44e457ddef7f2c4f25dc8fa865 | 609 + (8,79) | 855 | 5.458 | addfa9b7e234254d26e9c7f2af1005cb | 662 + (3,60) | 351 | 4.695 | efe937780e95574250dabe07151bdc23 | 606 + (9,51) | 924 | 7.052 | bea5955b308361a1b07bc55042e25e54 | 641 + (1,79) | 176 | 0.635 | 38af86134b65d0f10fe33d30dd76442e | 679 + (8,33) | 809 | 6.587 | 32b30a250abd6331e03a2a1f16466346 | 660 + (0,68) | 68 | 3.698 | a3f390d88e4c41f2747bfa2f1b5f87db | 664 + (10,2) | 972 | 7.836 | c22abfa379f38b5b0411bc11fa9bf92f | 609 + (2,44) | 238 | 9.606 | ac1dd209cbcc5e5d1c6e28598e8cbbe8 | 664 + (8,16) | 792 | 4.409 | 96ea64f3a1aa2fd00c72faacf0cb8ac9 | 597 + (4,9) | 397 | 9.307 | e46de7e1bcaaced9a54f1e9d0d2f800d | 669 + (6,3) | 585 | 2.718 | a9a1d5317a33ae8cef33961c34144f84 | 590 + (4,74) | 462 | 3.655 | 51d92be1c60d1db1d2e5e7a07da55b26 | 671 + (8,77) | 853 | 5.415 | aff1621254f7c1be92f64550478c56e6 | 630 + (8,28) | 804 | 0.202 | dc5689792e08eb2e219dce49e64c885b | 674 + (9,65) | 938 | 9.768 | 74bba22728b6185eec06286af6bec36d | 627 + (5,53) | 538 | 9.297 | 7bcdf75ad237b8e02e301f4091fb6bc8 | 619 + (1,87) | 184 | 7.903 | 6cdd60ea0045eb7a6ec44c54d29ed402 | 638 + (10,23) | 993 | 9.428 | 7b13b2203029ed80337f27127a9f1d28 | 640 + (9,81) | 954 | 5.503 | 6395ebd0f4b478145ecfbaf939454fa4 | 591 + (8,79) | 855 | 5.458 | addfa9b7e234254d26e9c7f2af1005cb | 650 + (5,42) | 527 | 9.387 | 13f320e7b5ead1024ac95c3b208610db | 605 + (3,50) | 341 | 7.735 | 3dd48ab31d016ffcbf3314df2b3cb9ce | 603 + (6,52) | 634 | 4.386 | 6766aa2750c19aad2fa1b32f36ed4aee | 621 + (4,53) | 441 | 6.968 | 15d4e891d784977cacbfcbb00c48f133 | 682 + (3,25) | 316 | 1.103 | 3fe94a002317b5f9259f82690aeea4cd | 627 + (9,20) | 893 | 1.805 | d56b9fc4b0f1be8871f5e1c40c0067e7 | 617 + (5,6) | 491 | 3.957 | 559cb990c9dffd8675f6bc2186971dc2 | 602 + (9,39) | 912 | 1.142 | 2a9d121cd9c3a1832bb6d2cc6bd7a8a7 | 653 + (0,71) | 71 | 3.292 | e2c420d928d4bf8ce0ff2ec19b371514 | 643 + (3,76) | 367 | 8.421 | 05049e90fa4f5039a8cadc6acbb4b2cc | 655 + (2,67) | 261 | 7.444 | b1a59b315fc9a3002ce38bbe070ec3f5 | 657 + (2,32) | 226 | 5.432 | 9cfdf10e8fc047a44b08ed031e1f0ed1 | 633 + (3,9) | 300 | 4.252 | 94f6d7e04a4d452035300f18b984988c | 671 + (5,25) | 510 | 2.627 | 087408522c31eeb1f982bc0eaf81d35f | 615 + (6,55) | 637 | 2.075 | a532400ed62e772b9dc0b86f46e583ff | 628 + (8,18) | 794 | 6.246 | 82489c9737cc245530c7a6ebef3753ec | 635 + (6,76) | 658 | 2.859 | 2f37d10131f2a483a8dd005b3d14b0d9 | 667 + (5,65) | 550 | 1.335 | 01f78be6f7cad02658508fe4616098a9 | 616 + (4,88) | 476 | 1.154 | 598b3e71ec378bd83e0a727608b5db01 | 655 + (5,51) | 536 | 4.951 | 65658fde58ab3c2b6e5132a39fae7cb9 | 596 + (10,15) | 985 | 6.823 | 54a367d629152b720749e187b3eaa11b | 648 + (8,48) | 824 | 0.742 | 677e09724f0e2df9b6c000b75b5da10d | 660 + (2,48) | 242 | 5.099 | e4a6222cdb5b34375400904f03d8e6a5 | 637 + (5,93) | 578 | 8.483 | a8849b052492b5106526b2331e526138 | 604 + (8,20) | 796 | 2.844 | 35cf8659cfcb13224cbd47863a34fc58 | 625 + (1,67) | 164 | 8.752 | fa7cdfad1a5aaf8370ebeda47a1ff1c3 | 649 + (0,82) | 82 | 7.493 | 9778d5d219c5080b9a6a17bef029331c | 594 + (9,37) | 910 | 0.305 | e205ee2a5de471a70c1fd1b46033a75f | 604 + (0,74) | 74 | 9.463 | ad61ab143223efbc24c7d2583be69251 | 681 + (4,36) | 424 | 2.163 | 3c7781a36bcd6cf08c11a970fbe0e2a6 | 634 + (1,23) | 120 | 9.306 | da4fb5c6e93e74d3df8527599fa62642 | 639 + (7,64) | 743 | 9.999 | 5c572eca050594c7bc3c36e7e8ab9550 | 682 + (0,6) | 6 | 1.83 | 1679091c5a880faf6fb5e6087eb1b2dc | 654 + (1,89) | 186 | 7.125 | 9872ed9fc22fc182d371c3e9ed316094 | 604 + (5,61) | 546 | 8.622 | ed265bc903a5a097f61d3ec064d96d2e | 624 + (7,69) | 748 | 0.086 | e49b8b4053df9505e1f48c3a701c0682 | 611 + (5,93) | 578 | 8.483 | a8849b052492b5106526b2331e526138 | 589 + (2,13) | 207 | 4.104 | 69adc1e107f7f7d035d7baf04342e1ca | 602 + (4,6) | 394 | 3.99 | 28f0b864598a1291557bed248a998d4e | 604 + (6,27) | 609 | 6.172 | d7a728a67d909e714c0774e22cb806f2 | 624 + (5,66) | 551 | 5.262 | 7f24d240521d99071c93af3917215ef7 | 590 + (2,12) | 206 | 2.416 | 7eabe3a1649ffa2b3ff8c02ebfd5659f | 589 + (5,94) | 579 | 9.939 | 258be18e31c8188555c2ff05b4d542c3 | 589 + (0,97) | 97 | 3.799 | e2ef524fbf3d9fe611d5a8e90fefdc9c | 589 + (2,80) | 274 | 3.661 | d947bf06a885db0d477d707121934ff8 | 680 + (1,22) | 119 | 2.819 | 07e1cd7dca89a1678042477183b7ac3f | 614 + (0,41) | 41 | 5.435 | 3416a75f4cea9109507cacd8e2f2aefc | 647 + (4,46) | 434 | 1.851 | a49e9411d64ff53eccfdd09ad10a15b3 | 603 + (6,54) | 636 | 9.116 | c5ab0bc60ac7929182aadd08703f1ec6 | 601 + (9,28) | 901 | 8.444 | 892c91e0a653ba19df81a90f89d99bcd | 663 + (1,84) | 181 | 6.904 | fc221309746013ac554571fbd180e1c8 | 672 + (3,77) | 368 | 7.943 | cf004fdc76fa1a4f25f62e0eb5261ca3 | 640 + (8,85) | 861 | 8.424 | f9a40a4780f5e1306c46f1c8daecee3b | 648 + (8,10) | 786 | 9.74 | 61b4a64be663682e8cb037d9719ad8cd | 667 + (1,40) | 137 | 1.045 | 3988c7f88ebcb58c6ce932b957b6f332 | 673 + (8,46) | 822 | 5.911 | afda332245e2af431fb7b672a68b659d | 612 + (0,47) | 47 | 9.07 | 67c6a1e7ce56d3d6fa748ab6d9af3fd7 | 645 + (1,41) | 138 | 5.781 | 013d407166ec4fa56eb1e1f8cbe183b9 | 645 + (5,20) | 505 | 0.208 | e8c0653fea13f91bf3c48159f7c24f78 | 673 + (2,39) | 233 | 9.268 | e165421110ba03099a1c0393373c5b43 | 661 + (4,10) | 398 | 6.664 | b7b16ecf8ca53723593894116071700c | 650 + (5,85) | 570 | 7.279 | a86c450b76fb8c371afead6410d55534 | 655 + (3,88) | 379 | 9.374 | a02ffd91ece5e7efeb46db8f10a74059 | 621 + (8,24) | 800 | 8.901 | 7a53928fa4dd31e82c6ef826f341daec | 622 + (5,78) | 563 | 8.07 | 8eefcfdf5990e441f0fb6f3fad709e21 | 601 + (3,83) | 374 | 4.769 | ad972f10e0800b49d76fed33a21f6698 | 597 + (8,26) | 802 | 4.672 | 1141938ba2c2b13f5505d7c424ebae5f | 608 + (8,51) | 827 | 3.585 | fa3a3c407f82377f55c19c5d403335c7 | 621 + (0,55) | 55 | 4.387 | b53b3a3d6ab90ce0268229151c9bde11 | 681 + (3,47) | 338 | 1.571 | 819f46e52c25763a55cc642422644317 | 645 + (5,33) | 518 | 9.49 | ebd9629fc3ae5e9f6611e2ee05a31cef | 597 + (2,66) | 260 | 7.864 | a4f23670e1833f3fdb077ca70bbd5d66 | 640 + (0,88) | 88 | 8.14 | 2a38a4a9316c49e5a833517c45d31070 | 592 + (8,13) | 789 | 3.511 | 68053af2923e00204c3ca7c6a3150cf7 | 647 +(709 rows) + +PREPARE p1(tid, tid) AS SELECT ctid,* FROM t1 + WHERE c like '%abc%' AND ctid BETWEEN $1 AND $2; +EXPLAIN (costs off) EXECUTE p1('(5,0)'::tid, '(10,0)'::tid); + QUERY PLAN +----------------------------------------------------------------------------------------- + Custom Scan (ctidscan) on t1 + Filter: ((c ~~ '%abc%'::text) AND (ctid >= '(5,0)'::tid) AND (ctid <= '(10,0)'::tid)) + ctid quals: ((ctid >= '(5,0)'::tid) AND (ctid <= '(10,0)'::tid)) +(3 rows) + +EXPLAIN (costs off) EXECUTE p1('(10,0)'::tid, '(5,0)'::tid); + QUERY PLAN +----------------------------------------------------------------------------------------- + Custom Scan (ctidscan) on t1 + Filter: ((c ~~ '%abc%'::text) AND (ctid >= '(10,0)'::tid) AND (ctid <= '(5,0)'::tid)) + ctid quals: ((ctid >= '(10,0)'::tid) AND (ctid <= '(5,0)'::tid)) +(3 rows) + +-- Also, EXPLAIN with none-text format +EXPLAIN (costs off, format xml) EXECUTE p1('(0,0)'::tid, '(5,0)'::tid); + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + + + + + + + Custom Scan + + ctidscan + + t1 + + t1 + + ((c ~~ '%abc%'::text) AND (ctid >= '(0,0)'::tid) AND (ctid <= '(5,0)'::tid))+ + ((ctid >= '(0,0)'::tid) AND (ctid <= '(5,0)'::tid)) + + + + + + +(1 row) + +-- Turn off the feature +SET enable_ctidscan = off; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; + QUERY PLAN +------------------------------------------------------------------ + Seq Scan on t1 + Filter: ((ctid >= '(2,115)'::tid) AND (ctid <= '(3,10)'::tid)) +(2 rows) + +-- Test Cleanup +DROP SCHEMA regtest_custom_scan CASCADE; +NOTICE: drop cascades to 3 other objects +DETAIL: drop cascades to table t1 +drop cascades to table t2 +drop cascades to table t3 diff --git a/src/test/modules/ctidscan/sql/ctidscan.sql b/src/test/modules/ctidscan/sql/ctidscan.sql new file mode 100644 index 0000000..c3ee864 --- /dev/null +++ b/src/test/modules/ctidscan/sql/ctidscan.sql @@ -0,0 +1,99 @@ +-- +-- Regression Tests for CustomScan Interface with CtidScan Provider +-- + +-- construction of test data +SET client_min_messages TO 'warning'; + +SET SEED TO 0.20140702; + +CREATE SCHEMA regtest_custom_scan; + +SET search_path TO regtest_custom_scan, public; + +CREATE TABLE t1 ( + a int primary key, + b float, + c text +); +INSERT INTO t1 (SELECT i, ceil(random()*10000.0) / 1000.0, md5(i::text) FROM generate_series(1,1000) i); +VACUUM ANALYZE t1; + +CREATE TABLE t2 ( + x int primary key, + y float, + z text +); +INSERT INTO t2 (SELECT i, ceil(random()*10000.0) / 1000.0, md5((-i)::text) FROM generate_series(201,1200) i); +VACUUM ANALYZE t2; + +CREATE TABLE t3 ( + a int references t1(a), + x int references t2(x) +); +INSERT INTO t3 (SELECT ceil(random() * 1000), ceil(random() * 1000) + 200 FROM generate_series(1,8000) i); + +RESET client_min_messages; +-- +-- Check Plans if no special extensions are loaded. +-- +EXPLAIN (costs off) SELECT * FROM t1 WHERE a = 40 AND ctid < '(6,0)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE c like '%789%' AND ctid < '(5,0)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid = '(2,10)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; +EXPLAIN (costs off) + SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND t2.x = t3.x + AND t1.ctid BETWEEN '(3,10)'::tid AND '(10,9999)'::tid + AND t2.ctid BETWEEN '(4,9999)'::tid AND '(8,0)'::tid + AND t3.ctid BETWEEN '(2,0)'::tid AND '(5,0)'::tid; +EXPLAIN (costs off, verbose) + SELECT count(*), ceil(b) + FROM t1 WHERE ctid BETWEEN '(3,0)'::tid AND '(10,0)'::tid + GROUP BY ceil(b); + +-- +-- Plan for same query but ctidscan was loaded +-- +LOAD '$libdir/ctidscan'; +EXPLAIN (costs off) SELECT * FROM t1 WHERE a = 40 AND ctid < '(6,0)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE c like '%789%' AND ctid < '(5,0)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid = '(2,10)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; +EXPLAIN (costs off) + SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND t2.x = t3.x + AND t1.ctid BETWEEN '(3,10)'::tid AND '(10,9999)'::tid + AND t2.ctid BETWEEN '(4,9999)'::tid AND '(8,0)'::tid + AND t3.ctid BETWEEN '(2,0)'::tid AND '(5,0)'::tid; +EXPLAIN (costs off, verbose) + SELECT count(*), ceil(b) + FROM t1 WHERE ctid BETWEEN '(3,0)'::tid AND '(10,0)'::tid + GROUP BY ceil(b); + +-- +-- Run the query without EXPLAIN +-- +SELECT ctid,* FROM t1 WHERE ctid <= '(1,20)'::tid; +SELECT ctid,* FROM t1 WHERE ctid > '(10,0)'::tid; +SELECT ctid,* FROM t1 WHERE c like '%678%' AND ctid >= '(3,50)'::tid; +SELECT ctid,* FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; +SELECT t1.ctid,* FROM t1 NATURAL JOIN t3 WHERE t3.ctid IN ( + SELECT t3.ctid FROM t2 NATURAL JOIN t3 + WHERE t2.ctid BETWEEN '(4,0)'::tid AND '(5,0)'::tid); + +PREPARE p1(tid, tid) AS SELECT ctid,* FROM t1 + WHERE c like '%abc%' AND ctid BETWEEN $1 AND $2; +EXPLAIN (costs off) EXECUTE p1('(5,0)'::tid, '(10,0)'::tid); +EXPLAIN (costs off) EXECUTE p1('(10,0)'::tid, '(5,0)'::tid); + +-- Also, EXPLAIN with none-text format +EXPLAIN (costs off, format xml) EXECUTE p1('(0,0)'::tid, '(5,0)'::tid); + +-- Turn off the feature +SET enable_ctidscan = off; + +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; + +-- Test Cleanup +DROP SCHEMA regtest_custom_scan CASCADE; diff --git a/src/test/regress/expected/custom_scan.out b/src/test/regress/expected/custom_scan.out new file mode 100644 index 0000000..e69de29 diff --git a/src/test/regress/sql/custom_scan.sql b/src/test/regress/sql/custom_scan.sql new file mode 100644 index 0000000..683154b --- /dev/null +++ b/src/test/regress/sql/custom_scan.sql @@ -0,0 +1,53 @@ +-- +-- Regression Tests for CustomScan Interface with CtidScan Provider +-- + +-- construction of test data +SET client_min_messages TO 'warning'; + +SET SEED 0.20140702; + +CREATE SCHEMA regtest_custom_scan; + +SET search_path TO regtest_custom_scan, public; + +CREATE TABLE t1 ( + a int primary key, + b float, + c text +); +INSERT INTO t1 (SELECT i, ceil(random()*1000.0) / 1000.0, md5(i::text) FROM generate_series(1,1000) i); +VACUUM ANALYZE t1; + +CREATE TABLE t2 ( + x int primary key, + y float, + z text +); +INSERT INTO t2 (SELECT i, ceil(random()*1000.0) / 1000.0, md5((-i)::text) FROM generate_series(201,1200) i); +VACUUM ANALYZE t2; + +CREATE TABLE t3 ( + a int references t1(a), + x int references t2(x) +); +INSERT INTO t3 (SELECT ceil(random() * 1000), ceil(random() * 1000) + 200 FROM generate_series(1,8000) i); + +RESET client_min_messages; +-- +-- Check Plans if no special extensions are loaded. +-- +EXPLAIN (costs off) SELECT * FROM t1 WHERE a = 40; +EXPLAIN (costs off) SELECT * FROM t1 WHERE b like '%789%'; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid = '(2,10)'::tid; +EXPLAIN (costs off) SELECT * FROM t1 WHERE ctid BETWEEN '(2,115)'::tid AND '(3,10)'::tid; +EXPLAIN (costs off) SELECT * FROM t1, t2, t3 + WHERE t1.a = t3.a AND t2.x = t3.x + AND t1.ctid BETWEEN '(3,10)'::tid AND '(10,9999)'::tid + AND t2.ctid BETWEEN '(4,9999)'::tid AND '(8.0)'::tid + AND t3.ctid BETWEEN '(2,0)'::tid AND '(5,0)'::tid; + + + +-- Test Cleanup +DROP SCHEMA regtest_custom_scan CASCADE;