blob: 3ad8700e1a57f49b39e3c584f12e8979e11ef65a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*
* execParquetScan.c
*
* Created on: Oct 11, 2013
* Author: malili
*/
#include "postgres.h"
#include "executor/executor.h"
#include "nodes/execnodes.h"
#include "cdb/cdbparquetam.h"
static void
InitParquetScanOpaque(ScanState *scanState)
{
ParquetScanState *state = (ParquetScanState *)scanState;
Assert(state->opaque == NULL);
state->opaque = palloc(sizeof(ParquetScanOpaqueData));
/* Initialize Parquet projection info */
ParquetScanOpaqueData *opaque = (ParquetScanOpaqueData *)state->opaque;
Relation currentRelation = scanState->ss_currentRelation;
Assert(currentRelation != NULL);
opaque->ncol = currentRelation->rd_att->natts;
opaque->proj = palloc0(sizeof(bool) * opaque->ncol);
GetNeededColumnsForScan((Node *)scanState->ps.plan->targetlist, opaque->proj, opaque->ncol);
GetNeededColumnsForScan((Node *)scanState->ps.plan->qual, opaque->proj, opaque->ncol);
int i = 0;
for (i = 0; i < opaque->ncol; i++)
{
if (opaque->proj[i])
{
break;
}
}
/*
* In some cases (for example, count(*)), no columns are specified.
* We always scan the first column.
*/
if (i == opaque->ncol)
{
opaque->proj[0] = true;
}
}
static void
FreeParquetScanOpaque(ScanState *scanState)
{
ParquetScanState *state = (ParquetScanState *)scanState;
Assert(state->opaque != NULL);
ParquetScanOpaqueData *opaque = (ParquetScanOpaqueData *)state->opaque;
Assert(opaque->proj != NULL);
pfree(opaque->proj);
pfree(state->opaque);
state->opaque = NULL;
}
TupleTableSlot *
ParquetScanNext(ScanState *scanState)
{
Assert(IsA(scanState, TableScanState) ||
IsA(scanState, DynamicTableScanState));
ParquetScanState *node = (ParquetScanState *)scanState;
Assert(node->opaque != NULL &&
node->opaque->scandesc != NULL);
/* push down Bloom filter */
if (node->opaque->scandesc->rfState == NULL &&
scanState->runtimeFilter != NULL)
{
node->opaque->scandesc->rfState = scanState->runtimeFilter;
}
parquet_getnext(node->opaque->scandesc, node->ss.ps.state->es_direction, node->ss.ss_ScanTupleSlot);
return node->ss.ss_ScanTupleSlot;
}
void
BeginScanParquetRelation(ScanState *scanState)
{
Assert(IsA(scanState, TableScanState) ||
IsA(scanState, DynamicTableScanState));
ParquetScanState *node = (ParquetScanState *)scanState;
Assert(node->ss.scan_state == SCAN_INIT || node->ss.scan_state == SCAN_DONE);
InitParquetScanOpaque(scanState);
node->opaque->scandesc = parquet_beginscan(
node->ss.ss_currentRelation,
node->ss.ps.state->es_snapshot,
NULL /* relationTupleDesc */,
node->opaque->proj);
/* push down Bloom filter */
node->opaque->scandesc->rfState = scanState->runtimeFilter;
node->opaque->scandesc->splits = scanState->splits;
node->ss.scan_state = SCAN_SCAN;
}
void
EndScanParquetRelation(ScanState *scanState)
{
Assert(IsA(scanState, TableScanState) ||
IsA(scanState, DynamicTableScanState));
ParquetScanState *node = (ParquetScanState *)scanState;
Assert((node->ss.scan_state & SCAN_SCAN) != 0);
Assert(node->opaque != NULL &&
node->opaque->scandesc != NULL);
parquet_endscan(node->opaque->scandesc);
FreeParquetScanOpaque(scanState);
node->ss.scan_state = SCAN_INIT;
}
void
ReScanParquetRelation(ScanState *scanState)
{
Assert(IsA(scanState, TableScanState) ||
IsA(scanState, DynamicTableScanState));
ParquetScanState *node = (ParquetScanState *)scanState;
Assert(node->opaque != NULL &&
node->opaque->scandesc != NULL);
parquet_rescan(node->opaque->scandesc);
}