mirror of https://github.com/citusdata/citus.git
Compare commits
11 Commits
Author | SHA1 | Date |
---|---|---|
|
8e5b9a06ad | |
|
aed6776d1f | |
|
a9dced4291 | |
|
34744501ce | |
|
86b57f426b | |
|
9801f743ce | |
|
8e3246a2f3 | |
|
1feb7102b8 | |
|
9cde3d4122 | |
|
7da6d68675 | |
|
a913b90ff3 |
|
@ -451,7 +451,7 @@ workflows:
|
|||
- build:
|
||||
name: build-14
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
|
||||
- check-style
|
||||
- check-sql-snapshots
|
||||
|
@ -607,74 +607,74 @@ workflows:
|
|||
- test-citus:
|
||||
name: 'test-14_check-multi'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-multi
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-multi-1'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-multi-1
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-mx'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-multi-mx
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-vanilla'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-vanilla
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-isolation'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-isolation
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-worker'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-worker
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-operations'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-operations
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-follower-cluster'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-follower-cluster
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-columnar'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-columnar
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-columnar-isolation'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-columnar-isolation
|
||||
requires: [build-14]
|
||||
- tap-test-citus:
|
||||
name: 'test_14_tap-recovery'
|
||||
pg_major: 14
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
suite: recovery
|
||||
requires: [build-14]
|
||||
- test-citus:
|
||||
name: 'test-14_check-failure'
|
||||
pg_major: 14
|
||||
image: citus/failtester
|
||||
image_tag: '14beta3'
|
||||
image_tag: '14rc1'
|
||||
make: check-failure
|
||||
requires: [build-14]
|
||||
|
||||
|
@ -689,14 +689,14 @@ workflows:
|
|||
name: 'test-12-14_check-pg-upgrade'
|
||||
old_pg_major: 12
|
||||
new_pg_major: 14
|
||||
image_tag: '12-13-14'
|
||||
image_tag: '12.8-13.4-14rc1'
|
||||
requires: [build-12,build-14]
|
||||
|
||||
- test-pg-upgrade:
|
||||
name: 'test-13-14_check-pg-upgrade'
|
||||
old_pg_major: 13
|
||||
new_pg_major: 14
|
||||
image_tag: '12-13-14'
|
||||
image_tag: '12.8-13.4-14rc1'
|
||||
requires: [build-13,build-14]
|
||||
|
||||
- test-citus-upgrade:
|
||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -1,3 +1,22 @@
|
|||
### citus v10.2.1 (September 24, 2021) ###
|
||||
|
||||
* Adds missing version-mismatch checks for columnar tables
|
||||
|
||||
* Adds missing version-mismatch checks for internal functions
|
||||
|
||||
* Fixes a bug that could cause partition shards being not co-located with
|
||||
parent shards
|
||||
|
||||
* Fixes a bug that prevents pushing down boolean expressions when using
|
||||
columnar custom scan
|
||||
|
||||
* Fixes a clog lookup failure that could occur when writing to a columnar table
|
||||
|
||||
* Fixes an issue that could cause unexpected errors when there is an
|
||||
in-progress write to a columnar table
|
||||
|
||||
* Revokes read access to `columnar.chunk` from unprivileged user
|
||||
|
||||
### citus v10.2.0 (September 14, 2021) ###
|
||||
|
||||
* Adds PostgreSQL 14 support
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for Citus 10.2devel.
|
||||
# Generated by GNU Autoconf 2.69 for Citus 10.2.1.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
|
@ -579,8 +579,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='Citus'
|
||||
PACKAGE_TARNAME='citus'
|
||||
PACKAGE_VERSION='10.2devel'
|
||||
PACKAGE_STRING='Citus 10.2devel'
|
||||
PACKAGE_VERSION='10.2.1'
|
||||
PACKAGE_STRING='Citus 10.2.1'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
@ -1260,7 +1260,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures Citus 10.2devel to adapt to many kinds of systems.
|
||||
\`configure' configures Citus 10.2.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1322,7 +1322,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of Citus 10.2devel:";;
|
||||
short | recursive ) echo "Configuration of Citus 10.2.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1425,7 +1425,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
Citus configure 10.2devel
|
||||
Citus configure 10.2.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -1908,7 +1908,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by Citus $as_me 10.2devel, which was
|
||||
It was created by Citus $as_me 10.2.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -5356,7 +5356,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by Citus $as_me 10.2devel, which was
|
||||
This file was extended by Citus $as_me 10.2.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -5418,7 +5418,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
Citus config.status 10.2devel
|
||||
Citus config.status 10.2.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# everyone needing autoconf installed, the resulting files are checked
|
||||
# into the SCM.
|
||||
|
||||
AC_INIT([Citus], [10.2devel])
|
||||
AC_INIT([Citus], [10.2.1])
|
||||
AC_COPYRIGHT([Copyright (c) Citus Data, Inc.])
|
||||
|
||||
# we'll need sed and awk for some of the version commands
|
||||
|
|
|
@ -605,10 +605,11 @@ RelationIdGetNumberOfAttributes(Oid relationId)
|
|||
/*
|
||||
* CheckVarStats() checks whether a qual involving this Var is likely to be
|
||||
* useful based on the correlation stats. If so, or if stats are unavailable,
|
||||
* return true; otherwise return false.
|
||||
* return true; otherwise return false and sets absVarCorrelation in case
|
||||
* caller wants to use for logging purposes.
|
||||
*/
|
||||
static bool
|
||||
CheckVarStats(PlannerInfo *root, Var *var, Oid sortop)
|
||||
CheckVarStats(PlannerInfo *root, Var *var, Oid sortop, float4 *absVarCorrelation)
|
||||
{
|
||||
/*
|
||||
* Collect isunique, ndistinct, and varCorrelation.
|
||||
|
@ -642,6 +643,14 @@ CheckVarStats(PlannerInfo *root, Var *var, Oid sortop)
|
|||
*/
|
||||
if (Abs(varCorrelation) < ColumnarQualPushdownCorrelationThreshold)
|
||||
{
|
||||
if (absVarCorrelation)
|
||||
{
|
||||
/*
|
||||
* Report absVarCorrelation if caller wants to know why given
|
||||
* var is rejected.
|
||||
*/
|
||||
*absVarCorrelation = Abs(varCorrelation);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -674,7 +683,7 @@ ExprReferencesRelid(Expr *expr, Index relid)
|
|||
|
||||
|
||||
/*
|
||||
* CheckPushdownClause tests to see if clause is a candidate for pushing down
|
||||
* ExtractPushdownClause extracts an Expr node from given clause for pushing down
|
||||
* into the given rel (including join clauses). This test may not be exact in
|
||||
* all cases; it's used to reduce the search space for parameterization.
|
||||
*
|
||||
|
@ -683,19 +692,134 @@ ExprReferencesRelid(Expr *expr, Index relid)
|
|||
* and that doesn't seem worth the effort. Here we just look for "Var op Expr"
|
||||
* or "Expr op Var", where Var references rel and Expr references other rels
|
||||
* (or no rels at all).
|
||||
*
|
||||
* Moreover, this function also looks into BoolExpr's to recursively extract
|
||||
* pushdownable OpExpr's of them:
|
||||
* i) AND_EXPR:
|
||||
* Take pushdownable args of AND expressions by ignoring the other args.
|
||||
* ii) OR_EXPR:
|
||||
* Ignore the whole OR expression if we cannot exract a pushdownable Expr
|
||||
* from one of its args.
|
||||
* iii) NOT_EXPR:
|
||||
* Simply ignore NOT expressions since we don't expect to see them before
|
||||
* an expression that we can pushdown, see the comment in function.
|
||||
*
|
||||
* The reasoning for those three rules could also be summarized as such;
|
||||
* for any expression that we cannot push-down, we must assume that it
|
||||
* evaluates to true.
|
||||
*
|
||||
* For example, given following WHERE clause:
|
||||
* (
|
||||
* (a > random() OR a < 30)
|
||||
* AND
|
||||
* a < 200
|
||||
* ) OR
|
||||
* (
|
||||
* a = 300
|
||||
* OR
|
||||
* a > 400
|
||||
* );
|
||||
* Even if we can pushdown (a < 30), we cannot pushdown (a > random() OR a < 30)
|
||||
* due to (a > random()). However, we can pushdown (a < 200), so we extract
|
||||
* (a < 200) from the lhs of the top level OR expression.
|
||||
*
|
||||
* For the rhs of the top level OR expression, since we can pushdown both (a = 300)
|
||||
* and (a > 400), we take this part as is.
|
||||
*
|
||||
* Finally, since both sides of the top level OR expression yielded pushdownable
|
||||
* expressions, we will pushdown the following:
|
||||
* (a < 200) OR ((a = 300) OR (a > 400))
|
||||
*/
|
||||
static bool
|
||||
CheckPushdownClause(PlannerInfo *root, RelOptInfo *rel, Expr *clause)
|
||||
static Expr *
|
||||
ExtractPushdownClause(PlannerInfo *root, RelOptInfo *rel, Node *node)
|
||||
{
|
||||
if (!IsA(clause, OpExpr) || list_length(((OpExpr *) clause)->args) != 2)
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
check_stack_depth();
|
||||
|
||||
if (node == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (IsA(node, BoolExpr))
|
||||
{
|
||||
BoolExpr *boolExpr = castNode(BoolExpr, node);
|
||||
if (boolExpr->boolop == NOT_EXPR)
|
||||
{
|
||||
/*
|
||||
* Standard planner should have already applied de-morgan rule to
|
||||
* simple NOT expressions. If we encounter with such an expression
|
||||
* here, then it can't be a pushdownable one, such as:
|
||||
* WHERE id NOT IN (SELECT id FROM something).
|
||||
*/
|
||||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"must not contain a subplan")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
List *pushdownableArgs = NIL;
|
||||
|
||||
Node *boolExprArg = NULL;
|
||||
foreach_ptr(boolExprArg, boolExpr->args)
|
||||
{
|
||||
Expr *pushdownableArg = ExtractPushdownClause(root, rel,
|
||||
(Node *) boolExprArg);
|
||||
if (pushdownableArg)
|
||||
{
|
||||
pushdownableArgs = lappend(pushdownableArgs, pushdownableArg);
|
||||
}
|
||||
else if (boolExpr->boolop == OR_EXPR)
|
||||
{
|
||||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"all arguments of an OR expression must be "
|
||||
"pushdownable but one of them was not, due "
|
||||
"to the reason given above")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* simply skip AND args that we cannot pushdown */
|
||||
}
|
||||
|
||||
int npushdownableArgs = list_length(pushdownableArgs);
|
||||
if (npushdownableArgs == 0)
|
||||
{
|
||||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"none of the arguments were pushdownable, "
|
||||
"due to the reason(s) given above ")));
|
||||
return NULL;
|
||||
}
|
||||
else if (npushdownableArgs == 1)
|
||||
{
|
||||
return (Expr *) linitial(pushdownableArgs);
|
||||
}
|
||||
|
||||
if (boolExpr->boolop == AND_EXPR)
|
||||
{
|
||||
return make_andclause(pushdownableArgs);
|
||||
}
|
||||
else if (boolExpr->boolop == OR_EXPR)
|
||||
{
|
||||
return make_orclause(pushdownableArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* already discarded NOT expr, so should not be reachable */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsA(node, OpExpr) || list_length(((OpExpr *) node)->args) != 2)
|
||||
{
|
||||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"must be binary operator expression")));
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OpExpr *opExpr = castNode(OpExpr, clause);
|
||||
OpExpr *opExpr = castNode(OpExpr, node);
|
||||
Expr *lhs = list_nth(opExpr->args, 0);
|
||||
Expr *rhs = list_nth(opExpr->args, 1);
|
||||
|
||||
|
@ -721,15 +845,15 @@ CheckPushdownClause(PlannerInfo *root, RelOptInfo *rel, Expr *clause)
|
|||
"must match 'Var <op> Expr' or 'Expr <op> Var'"),
|
||||
errhint("Var must only reference this rel, "
|
||||
"and Expr must not reference this rel")));
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (varSide->varattno <= 0)
|
||||
{
|
||||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"var is whole-row reference")));
|
||||
return false;
|
||||
"var is whole-row reference or system column")));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (contain_volatile_functions((Node *) exprSide))
|
||||
|
@ -737,7 +861,7 @@ CheckPushdownClause(PlannerInfo *root, RelOptInfo *rel, Expr *clause)
|
|||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"expr contains volatile functions")));
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* only the default opclass is used for qual pushdown. */
|
||||
|
@ -753,7 +877,7 @@ CheckPushdownClause(PlannerInfo *root, RelOptInfo *rel, Expr *clause)
|
|||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"cannot find default btree opclass and opfamily for type: %s",
|
||||
format_type_be(varSide->vartype))));
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!op_in_opfamily(opExpr->opno, varOpFamily))
|
||||
|
@ -762,7 +886,7 @@ CheckPushdownClause(PlannerInfo *root, RelOptInfo *rel, Expr *clause)
|
|||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"operator %d not a member of opfamily %d",
|
||||
opExpr->opno, varOpFamily)));
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Oid sortop = get_opfamily_member(varOpFamily, varOpcInType,
|
||||
|
@ -773,15 +897,20 @@ CheckPushdownClause(PlannerInfo *root, RelOptInfo *rel, Expr *clause)
|
|||
* Check that statistics on the Var support the utility of this
|
||||
* clause.
|
||||
*/
|
||||
if (!CheckVarStats(root, varSide, sortop))
|
||||
float4 absVarCorrelation = 0;
|
||||
if (!CheckVarStats(root, varSide, sortop, &absVarCorrelation))
|
||||
{
|
||||
ereport(ColumnarPlannerDebugLevel,
|
||||
(errmsg("columnar planner: cannot push down clause: "
|
||||
"var attribute %d is uncorrelated", varSide->varattno)));
|
||||
return false;
|
||||
"absolute correlation (%.3f) of var attribute %d is "
|
||||
"smaller than the value configured in "
|
||||
"\"columnar.qual_pushdown_correlation_threshold\" "
|
||||
"(%.3f)", absVarCorrelation, varSide->varattno,
|
||||
ColumnarQualPushdownCorrelationThreshold)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (Expr *) node;
|
||||
}
|
||||
|
||||
|
||||
|
@ -806,12 +935,19 @@ FilterPushdownClauses(PlannerInfo *root, RelOptInfo *rel, List *inputClauses)
|
|||
* there's something we should do with pseudoconstants here.
|
||||
*/
|
||||
if (rinfo->pseudoconstant ||
|
||||
!bms_is_member(rel->relid, rinfo->required_relids) ||
|
||||
!CheckPushdownClause(root, rel, rinfo->clause))
|
||||
!bms_is_member(rel->relid, rinfo->required_relids))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Expr *pushdownableExpr = ExtractPushdownClause(root, rel, (Node *) rinfo->clause);
|
||||
if (!pushdownableExpr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
rinfo = copyObject(rinfo);
|
||||
rinfo->clause = pushdownableExpr;
|
||||
filteredClauses = lappend(filteredClauses, rinfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -1178,8 +1178,18 @@ UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, bool *update,
|
|||
|
||||
heap_inplace_update(columnarStripes, modifiedTuple);
|
||||
|
||||
/*
|
||||
* Existing tuple now contains modifications, because we used
|
||||
* heap_inplace_update().
|
||||
*/
|
||||
HeapTuple newTuple = oldTuple;
|
||||
|
||||
/*
|
||||
* Must not pass modifiedTuple, because BuildStripeMetadata expects a real
|
||||
* heap tuple with MVCC fields.
|
||||
*/
|
||||
StripeMetadata *modifiedStripeMetadata = BuildStripeMetadata(columnarStripes,
|
||||
modifiedTuple);
|
||||
newTuple);
|
||||
|
||||
CommandCounterIncrement();
|
||||
|
||||
|
@ -1233,6 +1243,8 @@ ReadDataFileStripeList(uint64 storageId, Snapshot snapshot)
|
|||
|
||||
/*
|
||||
* BuildStripeMetadata builds a StripeMetadata object from given heap tuple.
|
||||
*
|
||||
* NB: heapTuple must be a proper heap tuple with MVCC fields.
|
||||
*/
|
||||
static StripeMetadata *
|
||||
BuildStripeMetadata(Relation columnarStripes, HeapTuple heapTuple)
|
||||
|
@ -1269,7 +1281,8 @@ BuildStripeMetadata(Relation columnarStripes, HeapTuple heapTuple)
|
|||
* subtransaction id here.
|
||||
*/
|
||||
TransactionId entryXmin = HeapTupleHeaderGetXmin(heapTuple->t_data);
|
||||
stripeMetadata->aborted = TransactionIdDidAbort(entryXmin);
|
||||
stripeMetadata->aborted = !TransactionIdIsInProgress(entryXmin) &&
|
||||
TransactionIdDidAbort(entryXmin);
|
||||
stripeMetadata->insertedByCurrentXact =
|
||||
TransactionIdIsCurrentTransactionId(entryXmin);
|
||||
|
||||
|
|
|
@ -173,6 +173,8 @@ columnar_beginscan(Relation relation, Snapshot snapshot,
|
|||
ParallelTableScanDesc parallel_scan,
|
||||
uint32 flags)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
int natts = relation->rd_att->natts;
|
||||
|
||||
/* attr_needed represents 0-indexed attribute numbers */
|
||||
|
@ -418,6 +420,8 @@ columnar_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan)
|
|||
static IndexFetchTableData *
|
||||
columnar_index_fetch_begin(Relation rel)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relfilenode = rel->rd_node.relNode;
|
||||
if (PendingWritesInUpperTransactions(relfilenode, GetCurrentSubTransactionId()))
|
||||
{
|
||||
|
@ -638,6 +642,8 @@ static bool
|
|||
columnar_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot,
|
||||
Snapshot snapshot)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
uint64 rowNumber = tid_to_row_number(slot->tts_tid);
|
||||
StripeMetadata *stripeMetadata = FindStripeByRowNumber(rel, rowNumber, snapshot);
|
||||
return stripeMetadata != NULL;
|
||||
|
@ -670,6 +676,8 @@ static void
|
|||
columnar_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid,
|
||||
int options, BulkInsertState bistate)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
/*
|
||||
* columnar_init_write_state allocates the write state in a longer
|
||||
* lasting context, so no need to worry about it.
|
||||
|
@ -716,6 +724,8 @@ static void
|
|||
columnar_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
|
||||
CommandId cid, int options, BulkInsertState bistate)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
ColumnarWriteState *writeState = columnar_init_write_state(relation,
|
||||
RelationGetDescr(relation),
|
||||
GetCurrentSubTransactionId());
|
||||
|
@ -790,6 +800,8 @@ columnar_relation_set_new_filenode(Relation rel,
|
|||
TransactionId *freezeXid,
|
||||
MultiXactId *minmulti)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
if (persistence == RELPERSISTENCE_UNLOGGED)
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
|
@ -825,6 +837,8 @@ columnar_relation_set_new_filenode(Relation rel,
|
|||
static void
|
||||
columnar_relation_nontransactional_truncate(Relation rel)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
RelFileNode relfilenode = rel->rd_node;
|
||||
|
||||
NonTransactionDropWriteState(relfilenode.relNode);
|
||||
|
@ -871,6 +885,8 @@ columnar_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
|
|||
double *tups_vacuumed,
|
||||
double *tups_recently_dead)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
TupleDesc sourceDesc = RelationGetDescr(OldHeap);
|
||||
TupleDesc targetDesc = RelationGetDescr(NewHeap);
|
||||
|
||||
|
@ -967,6 +983,15 @@ static void
|
|||
columnar_vacuum_rel(Relation rel, VacuumParams *params,
|
||||
BufferAccessStrategy bstrategy)
|
||||
{
|
||||
if (!CheckCitusVersion(WARNING))
|
||||
{
|
||||
/*
|
||||
* Skip if the extension catalogs are not up-to-date, but avoid
|
||||
* erroring during auto-vacuum.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If metapage version of relation is older, then we hint users to VACUUM
|
||||
* the relation in ColumnarMetapageCheckVersion. So if needed, upgrade
|
||||
|
@ -1276,6 +1301,8 @@ columnar_index_build_range_scan(Relation columnarRelation,
|
|||
void *callback_state,
|
||||
TableScanDesc scan)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
if (start_blockno != 0 || numblocks != InvalidBlockNumber)
|
||||
{
|
||||
/*
|
||||
|
@ -1524,6 +1551,8 @@ columnar_index_validate_scan(Relation columnarRelation,
|
|||
ValidateIndexState *
|
||||
validateIndexState)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
ColumnarReportTotalVirtualBlocks(columnarRelation, snapshot,
|
||||
PROGRESS_SCAN_BLOCKS_TOTAL);
|
||||
|
||||
|
@ -1694,6 +1723,8 @@ TupleSortSkipSmallerItemPointers(Tuplesortstate *tupleSort, ItemPointer targetIt
|
|||
static uint64
|
||||
columnar_relation_size(Relation rel, ForkNumber forkNumber)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
uint64 nblocks = 0;
|
||||
|
||||
/* Open it at the smgr level if not already done */
|
||||
|
@ -1719,6 +1750,8 @@ columnar_relation_size(Relation rel, ForkNumber forkNumber)
|
|||
static bool
|
||||
columnar_relation_needs_toast_table(Relation rel)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1728,6 +1761,8 @@ columnar_estimate_rel_size(Relation rel, int32 *attr_widths,
|
|||
BlockNumber *pages, double *tuples,
|
||||
double *allvisfrac)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
RelationOpenSmgr(rel);
|
||||
*pages = smgrnblocks(rel->rd_smgr, MAIN_FORKNUM);
|
||||
*tuples = ColumnarTableRowCount(rel);
|
||||
|
@ -1899,6 +1934,8 @@ ColumnarTableDropHook(Oid relid)
|
|||
|
||||
if (IsColumnarTableAmTable(relid))
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
/*
|
||||
* Drop metadata. No need to drop storage here since for
|
||||
* tableam tables storage is managed by postgres.
|
||||
|
@ -2020,6 +2057,8 @@ ColumnarProcessUtility(PlannedStmt *pstmt,
|
|||
GetCreateIndexRelationLockMode(indexStmt));
|
||||
if (rel->rd_tableam == GetColumnarTableAmRoutine())
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
if (!ColumnarSupportsIndexAM(indexStmt->accessMethod))
|
||||
{
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
|
@ -2356,6 +2395,8 @@ PG_FUNCTION_INFO_V1(alter_columnar_table_set);
|
|||
Datum
|
||||
alter_columnar_table_set(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
|
||||
Relation rel = table_open(relationId, AccessExclusiveLock); /* ALTER TABLE LOCK */
|
||||
|
@ -2483,6 +2524,8 @@ PG_FUNCTION_INFO_V1(alter_columnar_table_reset);
|
|||
Datum
|
||||
alter_columnar_table_reset(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
|
||||
Relation rel = table_open(relationId, AccessExclusiveLock); /* ALTER TABLE LOCK */
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
-- columnar--10.2-1--10.2-2.sql
|
||||
|
||||
-- revoke read access for columnar.chunk from unprivileged
|
||||
-- user as it contains chunk min/max values
|
||||
REVOKE SELECT ON columnar.chunk FROM PUBLIC;
|
|
@ -0,0 +1,4 @@
|
|||
-- columnar--10.2-2--10.2-1.sql
|
||||
|
||||
-- grant read access for columnar.chunk to unprivileged user
|
||||
GRANT SELECT ON columnar.chunk TO PUBLIC;
|
|
@ -1,6 +1,6 @@
|
|||
# Citus extension
|
||||
comment = 'Citus distributed database'
|
||||
default_version = '10.2-1'
|
||||
default_version = '10.2-2'
|
||||
module_pathname = '$libdir/citus'
|
||||
relocatable = false
|
||||
schema = pg_catalog
|
||||
|
|
|
@ -554,11 +554,16 @@ CreateDistributedTable(Oid relationId, Var *distributionColumn, char distributio
|
|||
{
|
||||
List *partitionList = PartitionList(relationId);
|
||||
Oid partitionRelationId = InvalidOid;
|
||||
Oid namespaceId = get_rel_namespace(relationId);
|
||||
char *schemaName = get_namespace_name(namespaceId);
|
||||
char *relationName = get_rel_name(relationId);
|
||||
char *parentRelationName = quote_qualified_identifier(schemaName, relationName);
|
||||
|
||||
foreach_oid(partitionRelationId, partitionList)
|
||||
{
|
||||
CreateDistributedTable(partitionRelationId, distributionColumn,
|
||||
distributionMethod, shardCount, false,
|
||||
colocateWithTableName, viaDeprecatedAPI);
|
||||
parentRelationName, viaDeprecatedAPI);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2061,6 +2061,8 @@ ShouldInitiateMetadataSync(bool *lockFailure)
|
|||
Datum
|
||||
citus_internal_add_partition_metadata(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
PG_ENSURE_ARGNOTNULL(0, "relation");
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
|
||||
|
@ -2211,6 +2213,8 @@ EnsurePartitionMetadataIsSane(Oid relationId, char distributionMethod, int coloc
|
|||
Datum
|
||||
citus_internal_add_shard_metadata(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
PG_ENSURE_ARGNOTNULL(0, "relation");
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
|
||||
|
@ -2426,6 +2430,8 @@ EnsureShardMetadataIsSane(Oid relationId, int64 shardId, char storageType,
|
|||
Datum
|
||||
citus_internal_add_placement_metadata(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
int64 shardId = PG_GETARG_INT64(0);
|
||||
int32 shardState = PG_GETARG_INT32(1);
|
||||
int64 shardLength = PG_GETARG_INT64(2);
|
||||
|
@ -2537,6 +2543,8 @@ ShouldSkipMetadataChecks(void)
|
|||
Datum
|
||||
citus_internal_update_placement_metadata(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
int64 shardId = PG_GETARG_INT64(0);
|
||||
int32 sourceGroupId = PG_GETARG_INT32(1);
|
||||
int32 targetGroupId = PG_GETARG_INT32(2);
|
||||
|
@ -2602,6 +2610,8 @@ citus_internal_update_placement_metadata(PG_FUNCTION_ARGS)
|
|||
Datum
|
||||
citus_internal_delete_shard_metadata(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
int64 shardId = PG_GETARG_INT64(0);
|
||||
|
||||
if (!ShouldSkipMetadataChecks())
|
||||
|
@ -2640,6 +2650,8 @@ citus_internal_delete_shard_metadata(PG_FUNCTION_ARGS)
|
|||
Datum
|
||||
citus_internal_update_relation_colocation(PG_FUNCTION_ARGS)
|
||||
{
|
||||
CheckCitusVersion(ERROR);
|
||||
|
||||
Oid relationId = PG_GETARG_OID(0);
|
||||
uint32 tagetColocationId = PG_GETARG_UINT32(1);
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
-- citus--10.2-1--10.2-2
|
||||
|
||||
-- bump version to 10.2-2
|
||||
|
||||
#include "../../columnar/sql/columnar--10.2-1--10.2-2.sql"
|
|
@ -0,0 +1,3 @@
|
|||
-- citus--10.2-2--10.2-1
|
||||
|
||||
#include "../../../columnar/sql/downgrades/columnar--10.2-2--10.2-1.sql"
|
|
@ -246,3 +246,6 @@ s/TRIM\(BOTH FROM value\)/btrim\(value\)/g
|
|||
s/pg14\.idx.*/pg14\.xxxxx/g
|
||||
|
||||
s/CREATE TABLESPACE test_tablespace LOCATION.*/CREATE TABLESPACE test_tablespace LOCATION XXXX/g
|
||||
|
||||
# columnar log for var correlation
|
||||
s/(.*absolute correlation \()([0,1]\.[0-9]+)(\) of var attribute [0-9]+ is smaller than.*)/\1X\.YZ\3/g
|
||||
|
|
|
@ -645,7 +645,7 @@ alter table coltest add column x5 int default (random()*20000)::int;
|
|||
analyze coltest;
|
||||
-- test that expressions on whole-row references are not pushed down
|
||||
select * from coltest where coltest = (1,1,1,1);
|
||||
NOTICE: columnar planner: cannot push down clause: var is whole-row reference
|
||||
NOTICE: columnar planner: cannot push down clause: var is whole-row reference or system column
|
||||
NOTICE: columnar planner: adding CustomScan path for coltest
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
id | x1 | x2 | x3 | x5
|
||||
|
@ -655,7 +655,7 @@ DETAIL: unparameterized; 0 clauses pushed down
|
|||
-- test that expressions on uncorrelated attributes are not pushed down
|
||||
set columnar.qual_pushdown_correlation to default;
|
||||
select * from coltest where x5 = 23484;
|
||||
NOTICE: columnar planner: cannot push down clause: var attribute 5 is uncorrelated
|
||||
NOTICE: columnar planner: cannot push down clause: absolute correlation (X.YZ) of var attribute 5 is smaller than the value configured in "columnar.qual_pushdown_correlation_threshold" (0.900)
|
||||
NOTICE: columnar planner: adding CustomScan path for coltest
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
id | x1 | x2 | x3 | x5
|
||||
|
@ -819,3 +819,250 @@ select * from numrange_test natural join numrange_test2 order by nr;
|
|||
|
||||
DROP TABLE atest1, atest2, t1, t2, t3, numrange_test, numrange_test2;
|
||||
set default_table_access_method to default;
|
||||
set columnar.planner_debug_level to notice;
|
||||
BEGIN;
|
||||
SET LOCAL columnar.stripe_row_limit = 2000;
|
||||
SET LOCAL columnar.chunk_group_row_limit = 1000;
|
||||
create table pushdown_test (a int, b int) using columnar;
|
||||
insert into pushdown_test values (generate_series(1, 200000));
|
||||
COMMIT;
|
||||
SET columnar.max_custom_scan_paths TO 50;
|
||||
SET columnar.qual_pushdown_correlation_threshold TO 0.0;
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=2 loops=1)
|
||||
Filter: ((a = 204356) OR (a = 104356) OR (a = 76556))
|
||||
Rows Removed by Filter: 1998
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: ((a = 204356) OR (a = 104356) OR (a = 76556))
|
||||
Columnar Chunk Groups Removed by Filter: 198
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
180912
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 194356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=3 loops=1)
|
||||
Filter: ((a = 194356) OR (a = 104356) OR (a = 76556))
|
||||
Rows Removed by Filter: 2997
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: ((a = 194356) OR (a = 104356) OR (a = 76556))
|
||||
Columnar Chunk Groups Removed by Filter: 197
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 194356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
375268
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a > a*-1 + b;
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: all arguments of an OR expression must be pushdownable but one of them was not, due to the reason given above
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=0 loops=1)
|
||||
Filter: ((a = 204356) OR (a > ((a * '-1'::integer) + b)))
|
||||
Rows Removed by Filter: 200000
|
||||
Columnar Projected Columns: a, b
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > 1000 and a < 10000) or (a > 20000 and a < 50000);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=38998 loops=1)
|
||||
Filter: (((a > 1000) AND (a < 10000)) OR ((a > 20000) AND (a < 50000)))
|
||||
Rows Removed by Filter: 2
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: (((a > 1000) AND (a < 10000)) OR ((a > 20000) AND (a < 50000)))
|
||||
Columnar Chunk Groups Removed by Filter: 161
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a > 1000 and a < 10000) or (a > 20000 and a < 50000);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
1099459500
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a < 2*a) or (a > 100);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: none of the arguments were pushdownable, due to the reason(s) given above
|
||||
NOTICE: columnar planner: cannot push down clause: all arguments of an OR expression must be pushdownable but one of them was not, due to the reason given above
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=200000 loops=1)
|
||||
Filter: ((((a)::double precision > random()) AND (a < (2 * a))) OR (a > 100))
|
||||
Columnar Projected Columns: a
|
||||
(4 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a < 2*a) or (a > 100);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: none of the arguments were pushdownable, due to the reason(s) given above
|
||||
NOTICE: columnar planner: cannot push down clause: all arguments of an OR expression must be pushdownable but one of them was not, due to the reason given above
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
20000100000
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a <= 2000) or (a > 200000-1010);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=3010 loops=1)
|
||||
Filter: ((((a)::double precision > random()) AND (a <= 2000)) OR (a > 198990))
|
||||
Rows Removed by Filter: 990
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: ((a <= 2000) OR (a > 198990))
|
||||
Columnar Chunk Groups Removed by Filter: 196
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a <= 2000) or (a > 200000-1010);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
203491455
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where
|
||||
(
|
||||
a > random()
|
||||
and
|
||||
(
|
||||
(a < 200 and a not in (select a from pushdown_test)) or
|
||||
(a > 1000 and a < 2000)
|
||||
)
|
||||
)
|
||||
or
|
||||
(a > 200000-2010);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must not contain a subplan
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=3009 loops=1)
|
||||
Filter: ((((a)::double precision > random()) AND (((a < 200) AND (NOT (SubPlan 1))) OR ((a > 1000) AND (a < 2000)))) OR (a > 197990))
|
||||
Rows Removed by Filter: 1991
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: (((a < 200) OR ((a > 1000) AND (a < 2000))) OR (a > 197990))
|
||||
Columnar Chunk Groups Removed by Filter: 195
|
||||
SubPlan 1
|
||||
-> Materialize (actual rows=100 loops=199)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test pushdown_test_1 (actual rows=199 loops=1)
|
||||
Columnar Projected Columns: a
|
||||
(11 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where
|
||||
(
|
||||
a > random()
|
||||
and
|
||||
(
|
||||
(a < 200 and a not in (select a from pushdown_test)) or
|
||||
(a > 1000 and a < 2000)
|
||||
)
|
||||
)
|
||||
or
|
||||
(a > 200000-2010);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must not contain a subplan
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
401479455
|
||||
(1 row)
|
||||
|
||||
create function stable_1(arg int) returns int language plpgsql STRICT IMMUTABLE as
|
||||
$$ BEGIN RETURN 1+arg; END; $$;
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a = random() and a < stable_1(a) and a < stable_1(6000));
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=0 loops=1)
|
||||
Filter: ((a < 6001) AND ((a)::double precision = random()) AND (a < stable_1(a)))
|
||||
Rows Removed by Filter: 6000
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: (a < 6001)
|
||||
Columnar Chunk Groups Removed by Filter: 194
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a = random() and a < stable_1(a) and a < stable_1(6000));
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
RESET columnar.max_custom_scan_paths;
|
||||
RESET columnar.qual_pushdown_correlation_threshold;
|
||||
RESET columnar.planner_debug_level;
|
||||
DROP TABLE pushdown_test;
|
||||
|
|
|
@ -645,7 +645,7 @@ alter table coltest add column x5 int default (random()*20000)::int;
|
|||
analyze coltest;
|
||||
-- test that expressions on whole-row references are not pushed down
|
||||
select * from coltest where coltest = (1,1,1,1);
|
||||
NOTICE: columnar planner: cannot push down clause: var is whole-row reference
|
||||
NOTICE: columnar planner: cannot push down clause: var is whole-row reference or system column
|
||||
NOTICE: columnar planner: adding CustomScan path for coltest
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
id | x1 | x2 | x3 | x5
|
||||
|
@ -655,7 +655,7 @@ DETAIL: unparameterized; 0 clauses pushed down
|
|||
-- test that expressions on uncorrelated attributes are not pushed down
|
||||
set columnar.qual_pushdown_correlation to default;
|
||||
select * from coltest where x5 = 23484;
|
||||
NOTICE: columnar planner: cannot push down clause: var attribute 5 is uncorrelated
|
||||
NOTICE: columnar planner: cannot push down clause: absolute correlation (X.YZ) of var attribute 5 is smaller than the value configured in "columnar.qual_pushdown_correlation_threshold" (0.900)
|
||||
NOTICE: columnar planner: adding CustomScan path for coltest
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
id | x1 | x2 | x3 | x5
|
||||
|
@ -819,3 +819,250 @@ select * from numrange_test natural join numrange_test2 order by nr;
|
|||
|
||||
DROP TABLE atest1, atest2, t1, t2, t3, numrange_test, numrange_test2;
|
||||
set default_table_access_method to default;
|
||||
set columnar.planner_debug_level to notice;
|
||||
BEGIN;
|
||||
SET LOCAL columnar.stripe_row_limit = 2000;
|
||||
SET LOCAL columnar.chunk_group_row_limit = 1000;
|
||||
create table pushdown_test (a int, b int) using columnar;
|
||||
insert into pushdown_test values (generate_series(1, 200000));
|
||||
COMMIT;
|
||||
SET columnar.max_custom_scan_paths TO 50;
|
||||
SET columnar.qual_pushdown_correlation_threshold TO 0.0;
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=2 loops=1)
|
||||
Filter: ((a = 204356) OR (a = 104356) OR (a = 76556))
|
||||
Rows Removed by Filter: 1998
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: ((a = 204356) OR (a = 104356) OR (a = 76556))
|
||||
Columnar Chunk Groups Removed by Filter: 198
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
180912
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 194356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=3 loops=1)
|
||||
Filter: ((a = 194356) OR (a = 104356) OR (a = 76556))
|
||||
Rows Removed by Filter: 2997
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: ((a = 194356) OR (a = 104356) OR (a = 76556))
|
||||
Columnar Chunk Groups Removed by Filter: 197
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 194356 or a = 104356 or a = 76556;
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
375268
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a > a*-1 + b;
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: all arguments of an OR expression must be pushdownable but one of them was not, due to the reason given above
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=0 loops=1)
|
||||
Filter: ((a = 204356) OR (a > ((a * '-1'::integer) + b)))
|
||||
Rows Removed by Filter: 200000
|
||||
Columnar Projected Columns: a, b
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > 1000 and a < 10000) or (a > 20000 and a < 50000);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=38998 loops=1)
|
||||
Filter: (((a > 1000) AND (a < 10000)) OR ((a > 20000) AND (a < 50000)))
|
||||
Rows Removed by Filter: 2
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: (((a > 1000) AND (a < 10000)) OR ((a > 20000) AND (a < 50000)))
|
||||
Columnar Chunk Groups Removed by Filter: 161
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a > 1000 and a < 10000) or (a > 20000 and a < 50000);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
1099459500
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a < 2*a) or (a > 100);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: none of the arguments were pushdownable, due to the reason(s) given above
|
||||
NOTICE: columnar planner: cannot push down clause: all arguments of an OR expression must be pushdownable but one of them was not, due to the reason given above
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=200000 loops=1)
|
||||
Filter: ((((a)::double precision > random()) AND (a < (2 * a))) OR (a > 100))
|
||||
Columnar Projected Columns: a
|
||||
(4 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a < 2*a) or (a > 100);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: none of the arguments were pushdownable, due to the reason(s) given above
|
||||
NOTICE: columnar planner: cannot push down clause: all arguments of an OR expression must be pushdownable but one of them was not, due to the reason given above
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
20000100000
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a <= 2000) or (a > 200000-1010);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=3010 loops=1)
|
||||
Filter: ((((a)::double precision > random()) AND (a <= 2000)) OR (a > 198990))
|
||||
Rows Removed by Filter: 990
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: ((a <= 2000) OR (a > 198990))
|
||||
Columnar Chunk Groups Removed by Filter: 196
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a <= 2000) or (a > 200000-1010);
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
203491455
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where
|
||||
(
|
||||
a > random()
|
||||
and
|
||||
(
|
||||
(a < 200 and a not in (select a from pushdown_test)) or
|
||||
(a > 1000 and a < 2000)
|
||||
)
|
||||
)
|
||||
or
|
||||
(a > 200000-2010);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must not contain a subplan
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=3009 loops=1)
|
||||
Filter: ((((a)::double precision > random()) AND (((a < 200) AND (NOT (SubPlan 1))) OR ((a > 1000) AND (a < 2000)))) OR (a > 197990))
|
||||
Rows Removed by Filter: 1991
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: (((a < 200) OR ((a > 1000) AND (a < 2000))) OR (a > 197990))
|
||||
Columnar Chunk Groups Removed by Filter: 195
|
||||
SubPlan 1
|
||||
-> Materialize (actual rows=100 loops=199)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test pushdown_test_1 (actual rows=199 loops=1)
|
||||
Columnar Projected Columns: a
|
||||
(11 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where
|
||||
(
|
||||
a > random()
|
||||
and
|
||||
(
|
||||
(a < 200 and a not in (select a from pushdown_test)) or
|
||||
(a > 1000 and a < 2000)
|
||||
)
|
||||
)
|
||||
or
|
||||
(a > 200000-2010);
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 0 clauses pushed down
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must not contain a subplan
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
401479455
|
||||
(1 row)
|
||||
|
||||
create function stable_1(arg int) returns int language plpgsql STRICT IMMUTABLE as
|
||||
$$ BEGIN RETURN 1+arg; END; $$;
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a = random() and a < stable_1(a) and a < stable_1(6000));
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Aggregate (actual rows=1 loops=1)
|
||||
-> Custom Scan (ColumnarScan) on pushdown_test (actual rows=0 loops=1)
|
||||
Filter: ((a < 6001) AND ((a)::double precision = random()) AND (a < stable_1(a)))
|
||||
Rows Removed by Filter: 6000
|
||||
Columnar Projected Columns: a
|
||||
Columnar Chunk Group Filters: (a < 6001)
|
||||
Columnar Chunk Groups Removed by Filter: 194
|
||||
(7 rows)
|
||||
|
||||
SELECT sum(a) FROM pushdown_test where (a = random() and a < stable_1(a) and a < stable_1(6000));
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: cannot push down clause: must match 'Var <op> Expr' or 'Expr <op> Var'
|
||||
HINT: Var must only reference this rel, and Expr must not reference this rel
|
||||
NOTICE: columnar planner: adding CustomScan path for pushdown_test
|
||||
DETAIL: unparameterized; 1 clauses pushed down
|
||||
sum
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
RESET columnar.max_custom_scan_paths;
|
||||
RESET columnar.qual_pushdown_correlation_threshold;
|
||||
RESET columnar.planner_debug_level;
|
||||
DROP TABLE pushdown_test;
|
||||
|
|
|
@ -750,6 +750,41 @@ SELECT * FROM multi_extension.print_extension_changes();
|
|||
| view public.citus_tables
|
||||
(2 rows)
|
||||
|
||||
-- not print "HINT: " to hide current lib version
|
||||
\set VERBOSITY terse
|
||||
CREATE TABLE columnar_table(a INT, b INT) USING columnar;
|
||||
SET citus.enable_version_checks TO ON;
|
||||
-- all should throw an error due to version mismatch
|
||||
VACUUM FULL columnar_table;
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
INSERT INTO columnar_table SELECT i FROM generate_series(1, 10) i;
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
VACUUM columnar_table;
|
||||
WARNING: loaded Citus library version differs from installed extension version
|
||||
TRUNCATE columnar_table;
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
DROP TABLE columnar_table;
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
CREATE INDEX ON columnar_table (a);
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
SELECT alter_columnar_table_set('columnar_table', compression => 'pglz');
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
SELECT alter_columnar_table_reset('columnar_table');
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
INSERT INTO columnar_table SELECT * FROM columnar_table;
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
SELECT 1 FROM columnar_table; -- columnar custom scan
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
SET columnar.enable_custom_scan TO OFF;
|
||||
SELECT 1 FROM columnar_table; -- seq scan
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
CREATE TABLE new_columnar_table (a int) USING columnar;
|
||||
ERROR: loaded Citus library version differs from installed extension version
|
||||
-- do cleanup for the rest of the tests
|
||||
SET citus.enable_version_checks TO OFF;
|
||||
DROP TABLE columnar_table;
|
||||
RESET columnar.enable_custom_scan;
|
||||
\set VERBOSITY default
|
||||
-- Test downgrade to 10.0-4 from 10.1-1
|
||||
ALTER EXTENSION citus UPDATE TO '10.1-1';
|
||||
ALTER EXTENSION citus UPDATE TO '10.0-4';
|
||||
|
@ -813,12 +848,28 @@ SELECT * FROM multi_extension.print_extension_changes();
|
|||
| function worker_nextval(regclass) integer
|
||||
(16 rows)
|
||||
|
||||
-- Test downgrade to 10.2-1 from 10.2-2
|
||||
ALTER EXTENSION citus UPDATE TO '10.2-2';
|
||||
ALTER EXTENSION citus UPDATE TO '10.2-1';
|
||||
-- Should be empty result since upgrade+downgrade should be a no-op
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
previous_object | current_object
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
-- Snapshot of state at 10.2-2
|
||||
ALTER EXTENSION citus UPDATE TO '10.2-2';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
previous_object | current_object
|
||||
---------------------------------------------------------------------
|
||||
(0 rows)
|
||||
|
||||
DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff;
|
||||
-- show running version
|
||||
SHOW citus.version;
|
||||
citus.version
|
||||
---------------------------------------------------------------------
|
||||
10.2devel
|
||||
10.2.1
|
||||
(1 row)
|
||||
|
||||
-- ensure no unexpected objects were created outside pg_catalog
|
||||
|
|
|
@ -265,19 +265,26 @@ SELECT * FROM columnar.stripe;
|
|||
|
||||
-- alter a columnar setting
|
||||
SET columnar.chunk_group_row_limit = 1050;
|
||||
DO $proc$
|
||||
BEGIN
|
||||
IF substring(current_Setting('server_version'), '\d+')::int >= 12 THEN
|
||||
EXECUTE $$
|
||||
-- create columnar table
|
||||
CREATE TABLE columnar_table (a int) USING columnar;
|
||||
-- alter a columnar table that is created by that unprivileged user
|
||||
SELECT alter_columnar_table_set('columnar_table', chunk_group_row_limit => 2000);
|
||||
alter_columnar_table_set
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- insert some data and read
|
||||
INSERT INTO columnar_table VALUES (1), (1);
|
||||
SELECT * FROM columnar_table;
|
||||
a
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
1
|
||||
(2 rows)
|
||||
|
||||
-- and drop it
|
||||
DROP TABLE columnar_table;
|
||||
$$;
|
||||
END IF;
|
||||
END$proc$;
|
||||
-- cannot modify columnar metadata table as unprivileged user
|
||||
INSERT INTO columnar.stripe VALUES(99);
|
||||
ERROR: permission denied for table stripe
|
||||
|
@ -286,6 +293,9 @@ ERROR: permission denied for table stripe
|
|||
-- (since citus extension has a dependency to it)
|
||||
DROP TABLE columnar.chunk;
|
||||
ERROR: must be owner of table chunk
|
||||
-- cannot read columnar.chunk since it could expose chunk min/max values
|
||||
SELECT * FROM columnar.chunk;
|
||||
ERROR: permission denied for table chunk
|
||||
-- test whether a read-only user can read from citus_tables view
|
||||
SELECT distribution_column FROM citus_tables WHERE table_name = 'test'::regclass;
|
||||
distribution_column
|
||||
|
|
|
@ -1028,6 +1028,46 @@ CREATE TABLE partitioned_users_table_2009 PARTITION OF partitioned_users_table F
|
|||
CREATE TABLE partitioned_events_table_2009 PARTITION OF partitioned_events_table FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');
|
||||
INSERT INTO partitioned_events_table SELECT * FROM events_table;
|
||||
INSERT INTO partitioned_users_table_2009 SELECT * FROM users_table;
|
||||
-- test distributed partitions are indeed colocated with the parent table
|
||||
CREATE TABLE sensors(measureid integer, eventdatetime date, measure_data jsonb, PRIMARY KEY (measureid, eventdatetime, measure_data))
|
||||
PARTITION BY RANGE(eventdatetime);
|
||||
CREATE TABLE sensors_old PARTITION OF sensors FOR VALUES FROM ('2000-01-01') TO ('2020-01-01');
|
||||
CREATE TABLE sensors_2020_01_01 PARTITION OF sensors FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
|
||||
CREATE TABLE sensors_new PARTITION OF sensors DEFAULT;
|
||||
SELECT create_distributed_table('sensors', 'measureid', colocate_with:='none');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT count(DISTINCT colocationid) FROM pg_dist_partition
|
||||
WHERE logicalrelid IN ('sensors'::regclass, 'sensors_old'::regclass, 'sensors_2020_01_01'::regclass, 'sensors_new'::regclass);
|
||||
count
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
CREATE TABLE local_sensors(measureid integer, eventdatetime date, measure_data jsonb, PRIMARY KEY (measureid, eventdatetime, measure_data))
|
||||
PARTITION BY RANGE(eventdatetime);
|
||||
CREATE TABLE local_sensors_old PARTITION OF local_sensors FOR VALUES FROM ('2000-01-01') TO ('2020-01-01');
|
||||
CREATE TABLE local_sensors_2020_01_01 PARTITION OF local_sensors FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
|
||||
CREATE TABLE local_sensors_new PARTITION OF local_sensors DEFAULT;
|
||||
SELECT create_distributed_table('local_sensors', 'measureid', colocate_with:='sensors');
|
||||
create_distributed_table
|
||||
---------------------------------------------------------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT count(DISTINCT colocationid) FROM pg_dist_partition
|
||||
WHERE logicalrelid IN ('sensors'::regclass, 'sensors_old'::regclass, 'sensors_2020_01_01'::regclass, 'sensors_new'::regclass,
|
||||
'local_sensors'::regclass, 'local_sensors_old'::regclass, 'local_sensors_2020_01_01'::regclass, 'local_sensors_new'::regclass);
|
||||
count
|
||||
---------------------------------------------------------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
DROP TABLE sensors;
|
||||
DROP TABLE local_sensors;
|
||||
--
|
||||
-- Complex JOINs, subqueries, UNIONs etc...
|
||||
--
|
||||
|
@ -1298,7 +1338,7 @@ INSERT INTO multi_column_partitioning VALUES(1, 1);
|
|||
INSERT INTO multi_column_partitioning_0_0_10_0 VALUES(5, -5);
|
||||
-- test INSERT to multi-column partitioned table where no suitable partition exists
|
||||
INSERT INTO multi_column_partitioning VALUES(10, 1);
|
||||
ERROR: no partition of relation "multi_column_partitioning_1660101" found for row
|
||||
ERROR: no partition of relation "multi_column_partitioning_1660133" found for row
|
||||
DETAIL: Partition key of the failing row contains (c1, c2) = (10, 1).
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
-- test with MINVALUE/MAXVALUE
|
||||
|
@ -1308,7 +1348,7 @@ INSERT INTO multi_column_partitioning VALUES(11, -11);
|
|||
INSERT INTO multi_column_partitioning_10_max_20_min VALUES(19, -19);
|
||||
-- test INSERT to multi-column partitioned table where no suitable partition exists
|
||||
INSERT INTO multi_column_partitioning VALUES(20, -20);
|
||||
ERROR: no partition of relation "multi_column_partitioning_1660101" found for row
|
||||
ERROR: no partition of relation "multi_column_partitioning_1660133" found for row
|
||||
DETAIL: Partition key of the failing row contains (c1, c2) = (20, -20).
|
||||
CONTEXT: while executing command on localhost:xxxxx
|
||||
-- see data is loaded to multi-column partitioned table
|
||||
|
|
|
@ -374,3 +374,74 @@ select * from numrange_test natural join numrange_test2 order by nr;
|
|||
DROP TABLE atest1, atest2, t1, t2, t3, numrange_test, numrange_test2;
|
||||
|
||||
set default_table_access_method to default;
|
||||
|
||||
set columnar.planner_debug_level to notice;
|
||||
|
||||
BEGIN;
|
||||
SET LOCAL columnar.stripe_row_limit = 2000;
|
||||
SET LOCAL columnar.chunk_group_row_limit = 1000;
|
||||
create table pushdown_test (a int, b int) using columnar;
|
||||
insert into pushdown_test values (generate_series(1, 200000));
|
||||
COMMIT;
|
||||
|
||||
SET columnar.max_custom_scan_paths TO 50;
|
||||
SET columnar.qual_pushdown_correlation_threshold TO 0.0;
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a = 104356 or a = 76556;
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a = 104356 or a = 76556;
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 194356 or a = 104356 or a = 76556;
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 194356 or a = 104356 or a = 76556;
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test WHERE a = 204356 or a > a*-1 + b;
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > 1000 and a < 10000) or (a > 20000 and a < 50000);
|
||||
SELECT sum(a) FROM pushdown_test where (a > 1000 and a < 10000) or (a > 20000 and a < 50000);
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a < 2*a) or (a > 100);
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a < 2*a) or (a > 100);
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a <= 2000) or (a > 200000-1010);
|
||||
SELECT sum(a) FROM pushdown_test where (a > random() and a <= 2000) or (a > 200000-1010);
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where
|
||||
(
|
||||
a > random()
|
||||
and
|
||||
(
|
||||
(a < 200 and a not in (select a from pushdown_test)) or
|
||||
(a > 1000 and a < 2000)
|
||||
)
|
||||
)
|
||||
or
|
||||
(a > 200000-2010);
|
||||
SELECT sum(a) FROM pushdown_test where
|
||||
(
|
||||
a > random()
|
||||
and
|
||||
(
|
||||
(a < 200 and a not in (select a from pushdown_test)) or
|
||||
(a > 1000 and a < 2000)
|
||||
)
|
||||
)
|
||||
or
|
||||
(a > 200000-2010);
|
||||
|
||||
create function stable_1(arg int) returns int language plpgsql STRICT IMMUTABLE as
|
||||
$$ BEGIN RETURN 1+arg; END; $$;
|
||||
|
||||
EXPLAIN (analyze on, costs off, timing off, summary off)
|
||||
SELECT sum(a) FROM pushdown_test where (a = random() and a < stable_1(a) and a < stable_1(6000));
|
||||
SELECT sum(a) FROM pushdown_test where (a = random() and a < stable_1(a) and a < stable_1(6000));
|
||||
|
||||
RESET columnar.max_custom_scan_paths;
|
||||
RESET columnar.qual_pushdown_correlation_threshold;
|
||||
RESET columnar.planner_debug_level;
|
||||
DROP TABLE pushdown_test;
|
||||
|
|
|
@ -297,6 +297,35 @@ ALTER EXTENSION citus UPDATE TO '9.5-1';
|
|||
ALTER EXTENSION citus UPDATE TO '10.0-4';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
-- not print "HINT: " to hide current lib version
|
||||
\set VERBOSITY terse
|
||||
CREATE TABLE columnar_table(a INT, b INT) USING columnar;
|
||||
SET citus.enable_version_checks TO ON;
|
||||
|
||||
-- all should throw an error due to version mismatch
|
||||
VACUUM FULL columnar_table;
|
||||
INSERT INTO columnar_table SELECT i FROM generate_series(1, 10) i;
|
||||
VACUUM columnar_table;
|
||||
TRUNCATE columnar_table;
|
||||
DROP TABLE columnar_table;
|
||||
CREATE INDEX ON columnar_table (a);
|
||||
SELECT alter_columnar_table_set('columnar_table', compression => 'pglz');
|
||||
SELECT alter_columnar_table_reset('columnar_table');
|
||||
INSERT INTO columnar_table SELECT * FROM columnar_table;
|
||||
|
||||
SELECT 1 FROM columnar_table; -- columnar custom scan
|
||||
|
||||
SET columnar.enable_custom_scan TO OFF;
|
||||
SELECT 1 FROM columnar_table; -- seq scan
|
||||
|
||||
CREATE TABLE new_columnar_table (a int) USING columnar;
|
||||
|
||||
-- do cleanup for the rest of the tests
|
||||
SET citus.enable_version_checks TO OFF;
|
||||
DROP TABLE columnar_table;
|
||||
RESET columnar.enable_custom_scan;
|
||||
\set VERBOSITY default
|
||||
|
||||
-- Test downgrade to 10.0-4 from 10.1-1
|
||||
ALTER EXTENSION citus UPDATE TO '10.1-1';
|
||||
ALTER EXTENSION citus UPDATE TO '10.0-4';
|
||||
|
@ -317,6 +346,16 @@ SELECT * FROM multi_extension.print_extension_changes();
|
|||
ALTER EXTENSION citus UPDATE TO '10.2-1';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
-- Test downgrade to 10.2-1 from 10.2-2
|
||||
ALTER EXTENSION citus UPDATE TO '10.2-2';
|
||||
ALTER EXTENSION citus UPDATE TO '10.2-1';
|
||||
-- Should be empty result since upgrade+downgrade should be a no-op
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
-- Snapshot of state at 10.2-2
|
||||
ALTER EXTENSION citus UPDATE TO '10.2-2';
|
||||
SELECT * FROM multi_extension.print_extension_changes();
|
||||
|
||||
DROP TABLE multi_extension.prev_objects, multi_extension.extension_diff;
|
||||
|
||||
-- show running version
|
||||
|
|
|
@ -162,19 +162,15 @@ SELECT * FROM columnar.stripe;
|
|||
-- alter a columnar setting
|
||||
SET columnar.chunk_group_row_limit = 1050;
|
||||
|
||||
DO $proc$
|
||||
BEGIN
|
||||
IF substring(current_Setting('server_version'), '\d+')::int >= 12 THEN
|
||||
EXECUTE $$
|
||||
-- create columnar table
|
||||
CREATE TABLE columnar_table (a int) USING columnar;
|
||||
-- alter a columnar table that is created by that unprivileged user
|
||||
SELECT alter_columnar_table_set('columnar_table', chunk_group_row_limit => 2000);
|
||||
-- insert some data and read
|
||||
INSERT INTO columnar_table VALUES (1), (1);
|
||||
SELECT * FROM columnar_table;
|
||||
-- and drop it
|
||||
DROP TABLE columnar_table;
|
||||
$$;
|
||||
END IF;
|
||||
END$proc$;
|
||||
|
||||
-- cannot modify columnar metadata table as unprivileged user
|
||||
INSERT INTO columnar.stripe VALUES(99);
|
||||
|
@ -183,6 +179,8 @@ INSERT INTO columnar.stripe VALUES(99);
|
|||
-- (since citus extension has a dependency to it)
|
||||
DROP TABLE columnar.chunk;
|
||||
|
||||
-- cannot read columnar.chunk since it could expose chunk min/max values
|
||||
SELECT * FROM columnar.chunk;
|
||||
|
||||
-- test whether a read-only user can read from citus_tables view
|
||||
SELECT distribution_column FROM citus_tables WHERE table_name = 'test'::regclass;
|
||||
|
|
|
@ -638,6 +638,35 @@ CREATE TABLE partitioned_events_table_2009 PARTITION OF partitioned_events_table
|
|||
INSERT INTO partitioned_events_table SELECT * FROM events_table;
|
||||
INSERT INTO partitioned_users_table_2009 SELECT * FROM users_table;
|
||||
|
||||
-- test distributed partitions are indeed colocated with the parent table
|
||||
CREATE TABLE sensors(measureid integer, eventdatetime date, measure_data jsonb, PRIMARY KEY (measureid, eventdatetime, measure_data))
|
||||
PARTITION BY RANGE(eventdatetime);
|
||||
|
||||
CREATE TABLE sensors_old PARTITION OF sensors FOR VALUES FROM ('2000-01-01') TO ('2020-01-01');
|
||||
CREATE TABLE sensors_2020_01_01 PARTITION OF sensors FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
|
||||
CREATE TABLE sensors_new PARTITION OF sensors DEFAULT;
|
||||
|
||||
SELECT create_distributed_table('sensors', 'measureid', colocate_with:='none');
|
||||
|
||||
SELECT count(DISTINCT colocationid) FROM pg_dist_partition
|
||||
WHERE logicalrelid IN ('sensors'::regclass, 'sensors_old'::regclass, 'sensors_2020_01_01'::regclass, 'sensors_new'::regclass);
|
||||
|
||||
CREATE TABLE local_sensors(measureid integer, eventdatetime date, measure_data jsonb, PRIMARY KEY (measureid, eventdatetime, measure_data))
|
||||
PARTITION BY RANGE(eventdatetime);
|
||||
|
||||
CREATE TABLE local_sensors_old PARTITION OF local_sensors FOR VALUES FROM ('2000-01-01') TO ('2020-01-01');
|
||||
CREATE TABLE local_sensors_2020_01_01 PARTITION OF local_sensors FOR VALUES FROM ('2020-01-01') TO ('2020-02-01');
|
||||
CREATE TABLE local_sensors_new PARTITION OF local_sensors DEFAULT;
|
||||
|
||||
SELECT create_distributed_table('local_sensors', 'measureid', colocate_with:='sensors');
|
||||
|
||||
SELECT count(DISTINCT colocationid) FROM pg_dist_partition
|
||||
WHERE logicalrelid IN ('sensors'::regclass, 'sensors_old'::regclass, 'sensors_2020_01_01'::regclass, 'sensors_new'::regclass,
|
||||
'local_sensors'::regclass, 'local_sensors_old'::regclass, 'local_sensors_2020_01_01'::regclass, 'local_sensors_new'::regclass);
|
||||
|
||||
DROP TABLE sensors;
|
||||
DROP TABLE local_sensors;
|
||||
|
||||
--
|
||||
-- Complex JOINs, subqueries, UNIONs etc...
|
||||
--
|
||||
|
|
Loading…
Reference in New Issue