blob: 7b46d3dd2865dc8333dae924247ba6162a118b5a [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* access/formatter.h
* Declarations for External Table Formatter functions
*
* 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.
*
*-------------------------------------------------------------------------
*/
#ifndef FORMATTER_H
#define FORMATTER_H
#include "access/tupdesc.h"
#include "lib/stringinfo.h"
#include "mb/pg_wchar.h"
#include "nodes/nodes.h"
#include "nodes/value.h"
#include "utils/rel.h"
typedef enum FmtNotification
{
FMT_NONE,
FMT_DONE,
FMT_NEED_MORE_DATA
} FmtNotification;
typedef enum FmtActionMask
{
FMT_UNSET = 0,
FMT_SET = 1,
FMT_NEEDEXTBUFF = 2,
FMT_WRITE_END = 4
} FmtActionMask;
/*
* FormatterData is the node type that is passed as fmgr "context" info
* when a function is called by the External Table Formatter manager.
*/
typedef struct FormatterData
{
NodeTag type; /* see T_FormatterData */
FmtActionMask fmt_mask;
/* metadata */
Relation fmt_relation;
TupleDesc fmt_tupDesc;
List *fmt_args;
FmtNotification fmt_notification;
HeapTuple fmt_tuple; /* hack! pass back the tuple through here for now... */
/* formatting */
StringInfoData fmt_databuf;
bool fmt_saw_eof;
FmgrInfo *fmt_conv_funcs; /* in_fuctions (RET) or out_functions (WET) */
Oid *fmt_typioparams;
MemoryContext fmt_perrow_ctx;
void *fmt_user_ctx;
/* sreh */
int fmt_badrow_num;
int fmt_badrow_len;
char *fmt_badrow_data;
int fmt_bytesread;
/* encoding */
bool fmt_needs_transcoding;
FmgrInfo* fmt_conversion_proc;
int fmt_external_encoding;
/* external url */
char *fmt_url;
/* splits */
List *fmt_splits;
} FormatterData;
#define CALLED_AS_FORMATTER(fcinfo) \
((fcinfo->context != NULL && IsA((fcinfo)->context, FormatterData)))
#define FORMATTER_GET_TUPDESC(fcinfo) (((FormatterData*) fcinfo->context)->fmt_tupDesc)
#define FORMATTER_GET_RELATION(fcinfo) (((FormatterData*) fcinfo->context)->fmt_relation)
#define FORMATTER_GET_DATABUF(fcinfo) (((FormatterData*) fcinfo->context)->fmt_databuf.data)
#define FORMATTER_GET_DATALEN(fcinfo) (((FormatterData*) fcinfo->context)->fmt_databuf.len)
#define FORMATTER_GET_DATACURSOR(fcinfo) (((FormatterData*) fcinfo->context)->fmt_databuf.cursor)
#define FORMATTER_GET_SAW_EOF(fcinfo) (((FormatterData*) fcinfo->context)->fmt_saw_eof)
#define FORMATTER_GET_USER_CTX(fcinfo) (((FormatterData*) fcinfo->context)->fmt_user_ctx)
#define FORMATTER_GET_PER_ROW_MEM_CTX(fcinfo) (((FormatterData*) fcinfo->context)->fmt_perrow_ctx)
#define FORMATTER_GET_CONVERSION_FUNCS(fcinfo) (((FormatterData*) fcinfo->context)->fmt_conv_funcs)
#define FORMATTER_GET_TYPIOPARAMS(fcinfo) (((FormatterData*) fcinfo->context)->fmt_typioparams)
#define FORMATTER_GET_ARG_LIST(fcinfo) (((FormatterData*) fcinfo->context)->fmt_args)
#define FORMATTER_GET_NUM_ARGS(fcinfo) (list_length(FORMATTER_GET_ARG_LIST(fcinfo)))
#define FORMATTER_GET_NTH_ARG_KEY(fcinfo, n) (((DefElem *)(list_nth(FORMATTER_GET_ARG_LIST(fcinfo),(n - 1))))->defname)
#define FORMATTER_GET_NTH_ARG_VAL(fcinfo, n) (((Value *)((DefElem *)(list_nth(FORMATTER_GET_ARG_LIST(fcinfo),(n - 1))))->arg)->val.str)
#define FORMATTER_GET_EXTENCODING(fcinfo) (((FormatterData*) fcinfo->context)->fmt_external_encoding)
#define FORMATTER_SET_USER_CTX(fcinfo, p) \
(((FormatterData*) fcinfo->context)->fmt_user_ctx = p)
#define FORMATTER_SET_BAD_ROW_NUM(fcinfo, n) \
(((FormatterData*) fcinfo->context)->fmt_badrow_num = n)
#define FORMATTER_SET_BAD_ROW_DATA(fcinfo, p, n) \
do { \
((FormatterData*) fcinfo->context)->fmt_badrow_len = n; \
((FormatterData*) fcinfo->context)->fmt_badrow_data = p; \
} while (0)
#define FORMATTER_SET_DATACURSOR(fcinfo, n) \
((((FormatterData*) fcinfo->context)->fmt_databuf.cursor) = n)
#define FORMATTER_SET_TUPLE(fcinfo, t) \
(((FormatterData*) fcinfo->context)->fmt_tuple = t)
#define FORMATTER_SET_BYTE_NUMBER(fcinfo, n) \
((((FormatterData*) fcinfo->context)->fmt_bytesread) += n)
#define FORMATTER_RETURN_TUPLE(tuple) \
PG_RETURN_DATUM(HeapTupleGetDatum(tuple))
#define FORMATTER_RETURN_NOTIFICATION(fcinfo, n) \
do { \
(((FormatterData*) fcinfo->context)->fmt_notification = n); \
PG_RETURN_NULL(); \
} while (0)
#define FORMATTER_ENCODE_STRING(fcinfo, p, n, cvt, is_import) \
do { \
if (((FormatterData*) fcinfo->context)->fmt_needs_transcoding) \
{\
if(is_import) \
cvt = pg_custom_to_server(p, \
n, \
((FormatterData*) fcinfo->context)->fmt_external_encoding, \
((FormatterData*) fcinfo->context)->fmt_conversion_proc); \
else \
cvt = pg_server_to_custom(p, \
n, \
((FormatterData*) fcinfo->context)->fmt_external_encoding, \
((FormatterData*) fcinfo->context)->fmt_conversion_proc); \
}\
} while (0)
#endif /* FORMATTER_H */