greenplumn gppc_demo 源码
greenplumn gppc_demo 代码
文件路径:/src/interfaces/gppc/test/gppc_demo.c
/*-------------------------------------------------------------------------
*
* gppc_test.c
* libgppc client program
*
* Portions Copyright (c) 2012, Greenplum Inc.
* Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates.
*
*
* IDENTIFICATION
* src/interfaces/gppc/test/gppc_demo/gppc_demo.c
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include <string.h>
#include "gppc.h"
GPPC_FUNCTION_INFO(oidcheckfunc);
GppcDatum oidcheckfunc(GPPC_FUNCTION_ARGS);
GppcDatum oidcheckfunc(GPPC_FUNCTION_ARGS)
{
char *arg = GppcTextGetCString(GPPC_GETARG_TEXT(0));
/*
* We use INT4 as the result type, because RETURN_OID macros are not prepared.
*/
if (strcmp("bool", arg) == 0)
GPPC_RETURN_INT4(GppcOidBool);
else if (strcmp("char", arg) == 0)
GPPC_RETURN_INT4(GppcOidChar);
else if (strcmp("int2", arg) == 0)
GPPC_RETURN_INT4(GppcOidInt2);
else if (strcmp("int4", arg) == 0)
GPPC_RETURN_INT4(GppcOidInt4);
else if (strcmp("int8", arg) == 0)
GPPC_RETURN_INT4(GppcOidInt8);
else if (strcmp("float4", arg) == 0)
GPPC_RETURN_INT4(GppcOidFloat4);
else if (strcmp("float8", arg) == 0)
GPPC_RETURN_INT4(GppcOidFloat8);
else if (strcmp("text", arg) == 0)
GPPC_RETURN_INT4(GppcOidText);
else if (strcmp("varchar", arg) == 0)
GPPC_RETURN_INT4(GppcOidVarChar);
else if (strcmp("bpchar", arg) == 0)
GPPC_RETURN_INT4(GppcOidBpChar);
else if (strcmp("bytea", arg) == 0)
GPPC_RETURN_INT4(GppcOidBytea);
else if (strcmp("numeric", arg) == 0)
GPPC_RETURN_INT4(GppcOidNumeric);
else if (strcmp("date", arg) == 0)
GPPC_RETURN_INT4(GppcOidDate);
else if (strcmp("time", arg) == 0)
GPPC_RETURN_INT4(GppcOidTime);
else if (strcmp("timetz", arg) == 0)
GPPC_RETURN_INT4(GppcOidTimeTz);
else if (strcmp("timestamp", arg) == 0)
GPPC_RETURN_INT4(GppcOidTimestamp);
else if (strcmp("timestamptz", arg) == 0)
GPPC_RETURN_INT4(GppcOidTimestampTz);
GPPC_RETURN_NULL();
}
GPPC_FUNCTION_INFO(boolfunc);
GppcDatum boolfunc(GPPC_FUNCTION_ARGS);
GppcDatum boolfunc(GPPC_FUNCTION_ARGS)
{
GppcBool arg1 = GPPC_GETARG_BOOL(0);
GPPC_RETURN_BOOL(arg1);
}
GPPC_FUNCTION_INFO(charfunc);
GppcDatum charfunc(GPPC_FUNCTION_ARGS);
GppcDatum charfunc(GPPC_FUNCTION_ARGS)
{
GppcChar arg1 = GPPC_GETARG_CHAR(0);
GPPC_RETURN_CHAR(arg1);
}
GPPC_FUNCTION_INFO(int2mulfunc);
GppcDatum int2mulfunc(GPPC_FUNCTION_ARGS);
GppcDatum int2mulfunc(GPPC_FUNCTION_ARGS)
{
GppcInt2 arg1 = GPPC_GETARG_INT2(0);
GppcInt2 arg2 = GPPC_GETARG_INT2(1);
GPPC_RETURN_INT2(arg1 * arg2);
}
GPPC_FUNCTION_INFO(int4func1);
GppcDatum int4func1(GPPC_FUNCTION_ARGS);
GppcDatum int4func1(GPPC_FUNCTION_ARGS)
{
int nargs = GPPC_NARGS();
GppcInt4 arg1;
if (nargs < 1)
arg1 = 0;
else
arg1 = GPPC_GETARG_INT4(0);
GPPC_RETURN_INT4(arg1);
}
GPPC_FUNCTION_INFO(int8plusfunc);
GppcDatum int8plusfunc(GPPC_FUNCTION_ARGS);
GppcDatum int8plusfunc(GPPC_FUNCTION_ARGS)
{
GppcInt8 arg1 = GPPC_GETARG_INT8(0);
GppcInt8 arg2 = GPPC_GETARG_INT8(1);
GPPC_RETURN_INT8(arg1 + arg2);
}
GPPC_FUNCTION_INFO(float4func1);
GppcDatum float4func1(GPPC_FUNCTION_ARGS);
GppcDatum float4func1(GPPC_FUNCTION_ARGS)
{
GppcFloat4 arg1 = GPPC_GETARG_FLOAT4(0);
GPPC_RETURN_FLOAT4(arg1 + 1.5);
}
GPPC_FUNCTION_INFO(float8func1);
GppcDatum float8func1(GPPC_FUNCTION_ARGS);
GppcDatum float8func1(GPPC_FUNCTION_ARGS)
{
GppcFloat8 arg1 = GPPC_GETARG_FLOAT8(0);
GPPC_RETURN_FLOAT8(arg1 / 2.0);
}
GPPC_FUNCTION_INFO(textdoublefunc);
GppcDatum textdoublefunc(GPPC_FUNCTION_ARGS);
GppcDatum textdoublefunc(GPPC_FUNCTION_ARGS)
{
GppcText arg1 = GPPC_GETARG_TEXT(0);
size_t clen = GppcGetTextLength(arg1);
GppcText result;
result = GppcAllocText(clen * 2);
memcpy(GppcGetTextPointer(result), GppcGetTextPointer(arg1), clen);
memcpy(GppcGetTextPointer(result) + clen, GppcGetTextPointer(arg1), clen);
GPPC_RETURN_TEXT(result);
}
GPPC_FUNCTION_INFO(textgenfunc);
GppcDatum textgenfunc(GPPC_FUNCTION_ARGS);
GppcDatum textgenfunc(GPPC_FUNCTION_ARGS)
{
GppcText result = GppcCStringGetText("cstring result");
GPPC_RETURN_TEXT(result);
}
GPPC_FUNCTION_INFO(textcopyfunc);
GppcDatum textcopyfunc(GPPC_FUNCTION_ARGS);
GppcDatum textcopyfunc(GPPC_FUNCTION_ARGS)
{
GppcText copy = GPPC_GETARG_TEXT_COPY(0);
GppcText arg = GPPC_GETARG_TEXT(0);
GppcBool needcopy = GPPC_GETARG_BOOL(1);
*(GppcGetTextPointer(copy)) = '!';
GPPC_RETURN_TEXT(needcopy ? copy : arg);
}
GPPC_FUNCTION_INFO(varchardoublefunc);
GppcDatum varchardoublefunc(GPPC_FUNCTION_ARGS);
GppcDatum varchardoublefunc(GPPC_FUNCTION_ARGS)
{
GppcVarChar arg1 = GPPC_GETARG_VARCHAR(0);
size_t clen = GppcGetVarCharLength(arg1);
GppcVarChar result;
result = GppcAllocVarChar(clen * 2);
memcpy(GppcGetVarCharPointer(result), GppcGetVarCharPointer(arg1), clen);
memcpy(GppcGetVarCharPointer(result) + clen, GppcGetVarCharPointer(arg1), clen);
GPPC_RETURN_VARCHAR(result);
}
GPPC_FUNCTION_INFO(varchargenfunc);
GppcDatum varchargenfunc(GPPC_FUNCTION_ARGS);
GppcDatum varchargenfunc(GPPC_FUNCTION_ARGS)
{
GppcVarChar result = GppcCStringGetVarChar("cstring result");
GPPC_RETURN_VARCHAR(result);
}
GPPC_FUNCTION_INFO(varcharcopyfunc);
GppcDatum varcharcopyfunc(GPPC_FUNCTION_ARGS);
GppcDatum varcharcopyfunc(GPPC_FUNCTION_ARGS)
{
GppcVarChar copy = GPPC_GETARG_VARCHAR_COPY(0);
GppcVarChar arg = GPPC_GETARG_VARCHAR(0);
GppcBool needcopy = GPPC_GETARG_BOOL(1);
*(GppcGetVarCharPointer(copy)) = '!';
GPPC_RETURN_VARCHAR(needcopy ? copy : arg);
}
GPPC_FUNCTION_INFO(bpchardoublefunc);
GppcDatum bpchardoublefunc(GPPC_FUNCTION_ARGS);
GppcDatum bpchardoublefunc(GPPC_FUNCTION_ARGS)
{
GppcBpChar arg1 = GPPC_GETARG_BPCHAR(0);
size_t clen = GppcGetBpCharLength(arg1);
GppcBpChar result;
result = GppcAllocBpChar(clen * 2);
memcpy(GppcGetBpCharPointer(result), GppcGetBpCharPointer(arg1), clen);
memcpy(GppcGetBpCharPointer(result) + clen, GppcGetBpCharPointer(arg1), clen);
GPPC_RETURN_BPCHAR(result);
}
GPPC_FUNCTION_INFO(bpchargenfunc);
GppcDatum bpchargenfunc(GPPC_FUNCTION_ARGS);
GppcDatum bpchargenfunc(GPPC_FUNCTION_ARGS)
{
GppcBpChar result = GppcCStringGetBpChar("cstring result");
GPPC_RETURN_BPCHAR(result);
}
GPPC_FUNCTION_INFO(bpcharcopyfunc);
GppcDatum bpcharcopyfunc(GPPC_FUNCTION_ARGS);
GppcDatum bpcharcopyfunc(GPPC_FUNCTION_ARGS)
{
GppcBpChar copy = GPPC_GETARG_BPCHAR_COPY(0);
GppcBpChar arg = GPPC_GETARG_BPCHAR(0);
GppcBool needcopy = GPPC_GETARG_BOOL(1);
*(GppcGetBpCharPointer(copy)) = '!';
GPPC_RETURN_BPCHAR(needcopy ? copy : arg);
}
GPPC_FUNCTION_INFO(errfunc1);
GppcDatum errfunc1(GPPC_FUNCTION_ARGS);
GppcDatum errfunc1(GPPC_FUNCTION_ARGS)
{
GppcText arg1 = GPPC_GETARG_TEXT(0);
char *cstr;
cstr = GppcTextGetCString(arg1);
GppcReport(GPPC_NOTICE, "%s", cstr);
GPPC_RETURN_NULL();
}
GPPC_FUNCTION_INFO(errfunc_varchar);
GppcDatum errfunc_varchar(GPPC_FUNCTION_ARGS);
GppcDatum errfunc_varchar(GPPC_FUNCTION_ARGS)
{
GppcVarChar tempBuf ;
GppcVarChar arg1 = GPPC_GETARG_VARCHAR(0);
size_t len = GppcGetVarCharLength(arg1);
tempBuf = GppcAllocVarChar(len);
char *cstr;
cstr = GppcVarCharGetCString(arg1);
GppcReport(GPPC_INFO, "%s", cstr);
/* Test GppcFree() */
memcpy(GppcGetVarCharPointer(tempBuf), GppcGetVarCharPointer(arg1), len);
GppcFree(tempBuf);
GPPC_RETURN_NULL();
}
GPPC_FUNCTION_INFO(errfunc_bpchar);
GppcDatum errfunc_bpchar(GPPC_FUNCTION_ARGS);
GppcDatum errfunc_bpchar(GPPC_FUNCTION_ARGS)
{
GppcBpChar arg1 = GPPC_GETARG_BPCHAR(0);
char *cstr;
cstr = GppcBpCharGetCString(arg1);
GppcReport(GPPC_WARNING, "%s", cstr);
GPPC_RETURN_NULL();
}
GPPC_FUNCTION_INFO(argisnullfunc);
GppcDatum argisnullfunc(GPPC_FUNCTION_ARGS);
GppcDatum argisnullfunc(GPPC_FUNCTION_ARGS)
{
if (GPPC_ARGISNULL(0))
GPPC_RETURN_BOOL(true);
else
GPPC_RETURN_BOOL(false);
}
GPPC_FUNCTION_INFO(gppc_func_text);
GppcDatum gppc_func_text(GPPC_FUNCTION_ARGS);
GppcDatum gppc_func_text(GPPC_FUNCTION_ARGS)
{
if (GppcGetDatabaseEncoding() != GPPC_UTF8) {
GppcReport(GPPC_ERROR, "Database encoding must be UTF8.");
GPPC_RETURN_NULL();
}
/* Using GppcDatabaseEncodingMaxLength() */
int len = GppcDatabaseEncodingMaxLength();
if (GPPC_NARGS() < 1) {
GppcText res;
char *buf;
/* Using GppcAlloc0(size_t); */
buf = GppcAlloc0(len);
char tempChar[] = "This gppc_func_text call has no arguments.";
buf = tempChar;
/* build GppcText from C string and reset the length of
variable length data */
res = GppcCStringGetText(buf);
GPPC_RETURN_TEXT(res);
} else {
GppcText res;
GppcText arg1 = GPPC_GETARG_TEXT(0);
GppcBool arg2 = true;
size_t clen = GppcGetTextLength(arg1);
if (GPPC_NARGS() > 1) { /* has 2nd argument */
arg2 = GPPC_GETARG_BOOL(1); /* assuming 2nd arg is a boolean */
}
char tempChar[] = "This gppc_func_text call has one or more arguments. ";
int cstrlen = strlen(tempChar);
/* Initialize using GppcAllocText */
if (arg2) {
res = GppcAllocText(cstrlen + clen);
/* Note GppcAllocText only initializes and allocates GppcText
without filling its content.
Need to use memcpy to fill the content.
Using GppcGetTextPointer() and GppcCStringGetText() */
memcpy(GppcGetTextPointer(res), GppcGetTextPointer(GppcCStringGetText(tempChar)), cstrlen);
memcpy(GppcGetTextPointer(res) + cstrlen, GppcGetTextPointer(arg1), clen);
} else {
res = GppcAllocText(cstrlen);
memcpy(GppcGetTextPointer(res), GppcGetTextPointer(GppcCStringGetText(tempChar)), cstrlen);
}
GPPC_RETURN_TEXT(res);
}
}
GPPC_FUNCTION_INFO(gppc_func_varchar);
GppcDatum gppc_func_varchar(GPPC_FUNCTION_ARGS);
GppcDatum gppc_func_varchar(GPPC_FUNCTION_ARGS)
{
GppcVarChar res;
/* Using GppcDatabaseEncodingMaxLength() */
int len = GppcDatabaseEncodingMaxLength();
if (GPPC_NARGS() < 1) {
char *buf;
/* Using GppcAlloc0(size_t) */
buf = GppcAlloc0(len);
char tempChar[] = "This gppc_func_varchar call has no arguments.";
buf = tempChar;
res = GppcCStringGetVarChar(buf);
GPPC_RETURN_VARCHAR(res);
} else {
char *buf;
/* Using GppcAlloc(size_t) */
buf = GppcAlloc(len);
/* Using GppcRealloc(char *, size_t) */
buf = GppcRealloc(buf, len * 2);
char tempChar[] = "This gppc_func_varchar call has one or more arguments.";
buf = tempChar;
/* build GppcText from C string and reset the length of
variable length data */
res = GppcCStringGetVarChar(buf);
GPPC_RETURN_VARCHAR(res);
}
}
GPPC_FUNCTION_INFO(byteafunc1);
GppcDatum byteafunc1(GPPC_FUNCTION_ARGS);
GppcDatum byteafunc1(GPPC_FUNCTION_ARGS)
{
GppcBytea bytea = GPPC_GETARG_BYTEA_COPY(0);
char *mem = GppcGetByteaPointer(bytea);
mem[0]++;
/* bytea2 should not be changed */
GppcBytea bytea2 = GPPC_GETARG_BYTEA(0);
GPPC_RETURN_BYTEA(bytea2);
}
GPPC_FUNCTION_INFO(byteafunc2);
GppcDatum byteafunc2(GPPC_FUNCTION_ARGS);
GppcDatum byteafunc2(GPPC_FUNCTION_ARGS)
{
GppcBytea bytea = GPPC_GETARG_BYTEA_COPY(0);
char *mem = GppcGetByteaPointer(bytea);
mem[0]++;
GPPC_RETURN_BYTEA(bytea);
}
GPPC_FUNCTION_INFO(numericfunc1);
GppcDatum numericfunc1(GPPC_FUNCTION_ARGS);
GppcDatum numericfunc1(GPPC_FUNCTION_ARGS)
{
GppcNumeric numeric = GPPC_GETARG_NUMERIC(0);
char *str;
str = GppcNumericGetCString(numeric);
if (strlen(str) > 0 && ('0' <= str[0] && str[0] <= '8'))
str[0]++;
GPPC_RETURN_NUMERIC(GppcCStringGetNumeric(str));
}
GPPC_FUNCTION_INFO(numericfunc2);
GppcDatum numericfunc2(GPPC_FUNCTION_ARGS);
GppcDatum numericfunc2(GPPC_FUNCTION_ARGS)
{
GppcNumeric numeric = GPPC_GETARG_NUMERIC(0);
GPPC_RETURN_FLOAT8(GppcNumericGetFloat8(numeric));
}
GPPC_FUNCTION_INFO(numericfunc3);
GppcDatum numericfunc3(GPPC_FUNCTION_ARGS);
GppcDatum numericfunc3(GPPC_FUNCTION_ARGS)
{
GppcFloat8 flt = GPPC_GETARG_FLOAT8(0);
GPPC_RETURN_NUMERIC(GppcFloat8GetNumeric(flt));
}
GPPC_FUNCTION_INFO(numericdef1);
GppcDatum numericdef1(GPPC_FUNCTION_ARGS);
GppcDatum numericdef1(GPPC_FUNCTION_ARGS)
{
GppcInt4 typmod = GPPC_GETARG_INT4(0);
int16_t precision, scale;
char buf[255];
if (GppcGetNumericDef(typmod, &precision, &scale))
snprintf(buf, 255, "NUMERIC(%d, %d)", precision, scale);
else
snprintf(buf, 255, "NUMERIC()");
GPPC_RETURN_TEXT(GppcCStringGetText(buf));
}
GPPC_FUNCTION_INFO(datefunc1);
GppcDatum datefunc1(GPPC_FUNCTION_ARGS);
GppcDatum datefunc1(GPPC_FUNCTION_ARGS)
{
GppcDate arg = GPPC_GETARG_DATE(0);
GppcTm tm;
GppcDateGetTm(arg, &tm);
tm.tm_year += 1;
tm.tm_mon += 1;
tm.tm_mday += 1;
GPPC_RETURN_DATE(GppcTmGetDate(&tm));
}
GPPC_FUNCTION_INFO(datefunc1_nochange);
GppcDatum datefunc1_nochange(GPPC_FUNCTION_ARGS);
GppcDatum datefunc1_nochange(GPPC_FUNCTION_ARGS)
{
GppcDate arg = GPPC_GETARG_DATE(0);
GppcTm tm;
GppcDateGetTm(arg, &tm);
GPPC_RETURN_DATE(GppcTmGetDate(&tm));
}
GPPC_FUNCTION_INFO(datefunc2);
GppcDatum datefunc2(GPPC_FUNCTION_ARGS);
GppcDatum datefunc2(GPPC_FUNCTION_ARGS)
{
GppcDate arg = GPPC_GETARG_DATE(0);
GppcTm tm;
GppcDateGetTm(arg, &tm);
tm.tm_year -= 1;
tm.tm_mon -= 1;
tm.tm_mday -= 1;
GPPC_RETURN_DATE(GppcTmGetDate(&tm));
}
GPPC_FUNCTION_INFO(datefunc3_year);
GppcDatum datefunc3_year(GPPC_FUNCTION_ARGS);
GppcDatum datefunc3_year(GPPC_FUNCTION_ARGS)
{
GppcDate arg = GPPC_GETARG_DATE(0);
GppcTm tm;
GppcDateGetTm(arg, &tm);
tm.tm_year -= 1;
GPPC_RETURN_DATE(GppcTmGetDate(&tm));
}
GPPC_FUNCTION_INFO(datefunc3_mon);
GppcDatum datefunc3_mon(GPPC_FUNCTION_ARGS);
GppcDatum datefunc3_mon(GPPC_FUNCTION_ARGS)
{
GppcDate arg = GPPC_GETARG_DATE(0);
GppcTm tm;
GppcDateGetTm(arg, &tm);
tm.tm_mon -= 1;
GPPC_RETURN_DATE(GppcTmGetDate(&tm));
}
GPPC_FUNCTION_INFO(datefunc3_mday);
GppcDatum datefunc3_mday(GPPC_FUNCTION_ARGS);
GppcDatum datefunc3_mday(GPPC_FUNCTION_ARGS)
{
GppcDate arg = GPPC_GETARG_DATE(0);
GppcTm tm;
GppcDateGetTm(arg, &tm);
tm.tm_mday -= 1;
GPPC_RETURN_DATE(GppcTmGetDate(&tm));
}
GPPC_FUNCTION_INFO(timefunc1);
GppcDatum timefunc1(GPPC_FUNCTION_ARGS);
GppcDatum timefunc1(GPPC_FUNCTION_ARGS)
{
GppcTime arg = GPPC_GETARG_TIME(0);
GppcTm tm;
GppcTimeGetTm(arg, &tm);
tm.tm_hour += 1;
tm.tm_min += 1;
tm.tm_sec += 1;
GPPC_RETURN_TIME(GppcTmGetTime(&tm));
}
GPPC_FUNCTION_INFO(timetzfunc1);
GppcDatum timetzfunc1(GPPC_FUNCTION_ARGS);
GppcDatum timetzfunc1(GPPC_FUNCTION_ARGS)
{
GppcTimeTz arg = GPPC_GETARG_TIMETZ(0);
GppcTm tm;
GppcTimeTzGetTm(arg, &tm);
tm.tm_hour += 1;
tm.tm_min += 1;
tm.tm_sec += 1;
GPPC_RETURN_TIMETZ(GppcTmGetTimeTz(&tm));
}
GPPC_FUNCTION_INFO(timestampfunc1);
GppcDatum timestampfunc1(GPPC_FUNCTION_ARGS);
GppcDatum timestampfunc1(GPPC_FUNCTION_ARGS)
{
GppcTimestamp arg = GPPC_GETARG_TIMESTAMP(0);
GppcTm tm;
GppcTimestampGetTm(arg, &tm);
tm.tm_year += 1;
tm.tm_mon += 1;
tm.tm_mday += 1;
tm.tm_hour += 1;
tm.tm_min += 1;
tm.tm_sec += 1;
GPPC_RETURN_TIMESTAMP(GppcTmGetTimestamp(&tm));
}
GPPC_FUNCTION_INFO(timestamptzfunc1);
GppcDatum timestamptzfunc1(GPPC_FUNCTION_ARGS);
GppcDatum timestamptzfunc1(GPPC_FUNCTION_ARGS)
{
GppcTimestampTz arg = GPPC_GETARG_TIMESTAMPTZ(0);
GppcTm tm;
GppcTimestampTzGetTm(arg, &tm);
tm.tm_year += 1;
tm.tm_mon += 1;
tm.tm_mday += 1;
tm.tm_hour += 1;
tm.tm_min += 1;
tm.tm_sec += 1;
GPPC_RETURN_TIMESTAMPTZ(GppcTmGetTimestampTz(&tm));
}
/*
* SPI test 1: run query, get the attribute by number at the final row as string
*/
GPPC_FUNCTION_INFO(spifunc1);
GppcDatum spifunc1(GPPC_FUNCTION_ARGS);
GppcDatum spifunc1(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
GppcInt4 attno = GPPC_GETARG_INT4(1);
GppcSPIResult result;
char *val = NULL;
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
result = GppcSPIExec(query, 0);
while (result->current < result->processed)
{
val = GppcSPIGetValue(result, attno, true);
result->current++;
}
GppcSPIFinish();
if (val)
GPPC_RETURN_TEXT(GppcCStringGetText(val));
else
GPPC_RETURN_NULL();
}
/*
* SPI test 2: run query, get the attribute by name at the final row as string
*/
GPPC_FUNCTION_INFO(spifunc2);
GppcDatum spifunc2(GPPC_FUNCTION_ARGS);
GppcDatum spifunc2(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
char *attname = GppcTextGetCString(GPPC_GETARG_TEXT(1));
GppcSPIResult result;
char *val = NULL;
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
result = GppcSPIExec(query, 0);
while (result->current < result->processed)
{
val = GppcSPIGetValueByName(result, attname, true);
result->current++;
}
GppcSPIFinish();
if (val)
GPPC_RETURN_TEXT(GppcCStringGetText(val));
else
GPPC_RETURN_NULL();
}
/*
* SPI test 3: run query, get the attribute by number at the final row as datum
*/
GPPC_FUNCTION_INFO(spifunc3);
GppcDatum spifunc3(GPPC_FUNCTION_ARGS);
GppcDatum spifunc3(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
GppcInt4 attno = GPPC_GETARG_INT4(1);
GppcSPIResult result;
GppcDatum datum = 0;
bool isnull = true;
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
result = GppcSPIExec(query, 0);
while (result->current < result->processed)
{
datum = GppcSPIGetDatum(result, attno, &isnull, true);
result->current++;
}
GppcSPIFinish();
if (!isnull)
GPPC_RETURN_TEXT(GppcDatumGetText(datum));
else
GPPC_RETURN_NULL();
}
/*
* SPI test 4: run query, get the attribute by name at the final row as datum
*/
GPPC_FUNCTION_INFO(spifunc4);
GppcDatum spifunc4(GPPC_FUNCTION_ARGS);
GppcDatum spifunc4(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
char *attname = GppcTextGetCString(GPPC_GETARG_TEXT(1));
GppcSPIResult result;
GppcDatum datum = 0;
bool isnull = true;
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
result = GppcSPIExec(query, 0);
while (result->current < result->processed)
{
datum = GppcSPIGetDatumByName(result, attname, &isnull, true);
result->current++;
}
GppcSPIFinish();
if (!isnull)
GPPC_RETURN_TEXT(GppcDatumGetText(datum));
else
GPPC_RETURN_NULL();
}
/*
* SPI test 5: select query, using tcount
*/
GPPC_FUNCTION_INFO(spifunc5);
GppcDatum spifunc5(GPPC_FUNCTION_ARGS);
GppcDatum spifunc5(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
GppcInt4 attno = GPPC_GETARG_INT4(1);
GppcInt4 tcount = GPPC_GETARG_INT4(2);
GppcSPIResult result;
char *val = NULL;
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
result = GppcSPIExec(query, tcount);
while (result->current < result->processed)
{
val = GppcSPIGetValue(result, attno, true);
result->current++;
}
GppcSPIFinish();
if (val)
GPPC_RETURN_TEXT(GppcCStringGetText(val));
else
GPPC_RETURN_NULL();
}
/*
* SPI test 5a: select query, using tcount, set makecopy = false
*/
GPPC_FUNCTION_INFO(spifunc5a);
GppcDatum spifunc5a(GPPC_FUNCTION_ARGS);
GppcDatum spifunc5a(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
GppcInt4 attno = GPPC_GETARG_INT4(1);
GppcInt4 tcount = GPPC_GETARG_INT4(2);
GppcSPIResult result;
char *val = NULL;
GppcInt4 count = 0; // count the total number of chars in the result set.
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
result = GppcSPIExec(query, tcount);
while (result->current < result->processed)
{
val = GppcSPIGetValue(result, attno, false); //set makcopy = false
count += strlen(val);
result->current++;
}
GppcSPIFinish();
GPPC_RETURN_INT4(count);
}
/*
* SPI test 6: run DML query, using tcount, return NULL
*/
GPPC_FUNCTION_INFO(spifunc6);
GppcDatum spifunc6(GPPC_FUNCTION_ARGS);
GppcDatum spifunc6(GPPC_FUNCTION_ARGS)
{
char *query = GppcTextGetCString(GPPC_GETARG_TEXT(0));
GppcInt4 tcount = GPPC_GETARG_INT4(1);
/* connTestFlag for connection test
* 1: connect again when already connected
* 2: try to execute without connection
* 3: close connection again when it has been closed already
*/
GppcInt4 connTestFlag = GPPC_GETARG_INT4(2);
GppcSPIResult result;
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error");
if (connTestFlag == 1)
{
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "connect error: already connected and cannot connect again.");
}
else if (connTestFlag == 2)
{
GppcSPIFinish();
}
result = GppcSPIExec(query, tcount);
if (result->rescode < 0)
{
GppcReport(GPPC_ERROR, "query execution error: Connection has been closed unexpectedly." );
}
GppcSPIFinish();
if (connTestFlag == 3)
{
if (GppcSPIFinish() < 0)
GppcReport(GPPC_ERROR, "connect error: connection has been closed and cannot be closed again.");
}
GPPC_RETURN_NULL();
}
/*
* The error handler. We can call GppcReport with INFO when ERROR, since it's not
* infinite recursion. For test purpose, set 'x' to message when WARNING.
*/
static void
errorcallback(GppcReportInfo info, void *arg)
{
GppcText message;
GppcReportLevel elevel = GppcGetReportLevel(info);
const char *rptMessage = GppcGetReportMessage(info);
size_t len = strlen(rptMessage);
message = GppcAllocText(len);
memcpy(GppcGetTextPointer(message), rptMessage, len);
if (elevel == GPPC_WARNING && arg)
memset(GppcGetTextPointer(arg), 'x', GppcGetTextLength(arg));
else if (elevel == GPPC_ERROR && arg)
GppcReport(GPPC_INFO, "inside callback: %s", GppcTextGetCString(arg));
else if (elevel == GPPC_NOTICE && arg)
GppcReport(GPPC_INFO, "inside callback message is: %s", rptMessage);
}
GPPC_FUNCTION_INFO(errorcallbackfunc1);
GppcDatum errorcallbackfunc1(GPPC_FUNCTION_ARGS);
GppcDatum
errorcallbackfunc1(GPPC_FUNCTION_ARGS)
{
GppcText arg = GPPC_GETARG_TEXT_COPY(0);
char *carg = GppcTextGetCString(arg);
GppcReportCallbackState cbinfo;
cbinfo = GppcInstallReportCallback(errorcallback, arg);
if (strcmp(carg, "info") == 0)
GppcReport(GPPC_INFO, "info emit");
else if (strcmp(carg, "warning") == 0)
GppcReport(GPPC_WARNING, "warning emit");
else if (strcmp(carg, "notice") == 0)
GppcReport(GPPC_NOTICE, "notice emit");
else if (strcmp(carg, "error") == 0)
GppcReport(GPPC_ERROR, "error emit");
GppcUninstallReportCallback(cbinfo);
GPPC_RETURN_TEXT(arg);
}
#if GP_VERSION_NUM >= 40200
GPPC_FUNCTION_INFO(tablefunc_describe);
GppcDatum tablefunc_describe(GPPC_FUNCTION_ARGS);
GppcDatum
tablefunc_describe(GPPC_FUNCTION_ARGS)
{
GppcText arg = GppcCStringGetText("Error callback in describe function");
GppcTupleDesc tdesc;
GppcInt4 avalue;
bool isnull, iserror;
GppcTupleDesc odesc;
GppcReportCallbackState cbstate;
/* For a test purpose to make sure it's working in the describe func */
cbstate = GppcInstallReportCallback(errorcallback, arg);
/* Fetch and validate input */
if (GPPC_NARGS() != 1 || GPPC_ARGISNULL(0))
GppcReport(GPPC_ERROR, "invalid invocation of describe");
/* Now get the tuple descriptor for the ANYTABLE we received */
tdesc = GPPC_TF_INPUT_DESC(0, &iserror);
if (iserror)
GppcReport(GPPC_ERROR, "cannot build tuple descriptor");
avalue = GPPC_TF_GETARG_INT4(1, &isnull, &iserror);
if (iserror)
GppcReport(GPPC_ERROR, "function is mal-declared");
if (isnull)
GppcReport(GPPC_ERROR, "the second argument should not be NULL");
if (avalue < 1 || avalue > GppcTupleDescNattrs(tdesc))
GppcReport(GPPC_ERROR, "invalid column position %d", avalue);
/* Print out the attlen -- just an excuse to use GppcTupleDescAttrLen() */
GppcReport(GPPC_NOTICE, "attlen is %d", GppcTupleDescAttrLen(tdesc, avalue - 1));
/* Build an output tuple a single column based on the column number above */
odesc = GppcCreateTemplateTupleDesc(1);
GppcTupleDescInitEntry(odesc, 1,
GppcTupleDescAttrName(tdesc, avalue - 1),
GppcTupleDescAttrType(tdesc, avalue - 1),
GppcTupleDescAttrTypmod(tdesc, avalue - 1));
GppcUninstallReportCallback(cbstate);
/* Finally return that tupdesc */
GPPC_RETURN_TUPLEDESC(odesc);
}
GPPC_FUNCTION_INFO(tablefunc_project);
GppcDatum tablefunc_project(GPPC_FUNCTION_ARGS);
GppcDatum
tablefunc_project(GPPC_FUNCTION_ARGS)
{
GppcFuncCallContext fctx;
GppcAnyTable scan;
GppcTupleDesc out_tupdesc, in_tupdesc;
GppcHeapTuple tuple;
int position;
GppcDatum values[1];
bool nulls[1];
GppcDatum result;
/*
* Sanity checking, shouldn't occur if our CREATE FUNCTION in SQL is done
* correctly.
*/
if (GPPC_NARGS() != 2 || GPPC_ARGISNULL(0) || GPPC_ARGISNULL(1))
GppcReport(GPPC_ERROR, "invalid invocation of project");
scan = GPPC_GETARG_ANYTABLE(0);
position = GPPC_GETARG_INT4(1);
/* Basic set-returning function (SRF) protocol, setup the context */
if (GPPC_SRF_IS_FIRSTCALL())
{
fctx = GPPC_SRF_FIRSTCALL_INIT();
}
fctx = GPPC_SRF_PERCALL_SETUP();
/* Get the next value from the input scan */
out_tupdesc = GPPC_SRF_RESULT_DESC();
in_tupdesc = GppcAnyTableGetTupleDesc(scan);
tuple = GppcAnyTableGetNextTuple(scan);
/* Based on what the describe callback should have setup */
if (position < 1 || position > GppcTupleDescNattrs(in_tupdesc))
GppcReport(GPPC_ERROR, "invalid column position(%d)", position);
if (GppcTupleDescNattrs(out_tupdesc) != 1)
GppcReport(GPPC_ERROR, "invalid column length in out_tupdesc");
if (GppcTupleDescAttrType(out_tupdesc, 0) !=
GppcTupleDescAttrType(in_tupdesc, 0))
GppcReport(GPPC_ERROR, "type mismatch");
/* check for end of scan */
if (tuple == NULL)
GPPC_SRF_RETURN_DONE(fctx);
/* Construct the output tuple and convert to a datum */
values[0] = GppcGetAttributeByNum(tuple, position, &nulls[0]);
result = GppcBuildHeapTupleDatum(out_tupdesc, values, nulls);
/* Return the next result */
GPPC_SRF_RETURN_NEXT(fctx, result);
}
GPPC_FUNCTION_INFO(describe_spi);
GppcDatum describe_spi(GPPC_FUNCTION_ARGS);
GppcDatum describe_spi(GPPC_FUNCTION_ARGS)
{
GppcTupleDesc tdesc, odesc;
GppcSPIResult result;
bool isnull, iserror;
char *query;
char *colname = NULL;
GppcDatum d_colname;
tdesc = GPPC_TF_INPUT_DESC(0, &iserror);
if (GppcSPIConnect() < 0)
GppcReport(GPPC_ERROR, "unable to connect to SPI");
/* Get query string */
query = GppcTextGetCString(GPPC_TF_GETARG_TEXT(1, &isnull, &iserror));
if (isnull || iserror)
GppcReport(GPPC_ERROR, "invalid invocation of describe_spi");
result = GppcSPIExec(query, 0);
if (result->processed > 0)
colname = GppcSPIGetValue(result, 1, true);
if (colname == NULL)
colname = "?column?";
GppcSPIFinish();
/* Build tuple desc */
odesc = GppcCreateTemplateTupleDesc(1);
GppcTupleDescInitEntry(odesc, 1,
colname, GppcOidText, -1);
d_colname = GppcTextGetDatum(GppcCStringGetText(colname));
/* Pass the query to project */
GPPC_TF_SET_USERDATA(GppcDatumGetByteaCopy(d_colname));
GPPC_RETURN_TUPLEDESC(odesc);
}
GPPC_FUNCTION_INFO(project_spi);
GppcDatum project_spi(GPPC_FUNCTION_ARGS);
GppcDatum project_spi(GPPC_FUNCTION_ARGS)
{
GppcFuncCallContext fctx;
GppcAnyTable scan;
GppcTupleDesc odesc, idesc;
GppcHeapTuple tuple;
char colname[255];
GppcDatum values[1];
bool isnull[1];
GppcDatum result;
scan = GPPC_GETARG_ANYTABLE(0);
/* Get the user context from the describe function */
strcpy(colname,
GppcTextGetCString(GppcDatumGetText(GppcByteaGetDatum(GPPC_TF_GET_USERDATA()))));
if (GPPC_SRF_IS_FIRSTCALL())
{
fctx = GPPC_SRF_FIRSTCALL_INIT();
}
fctx = GPPC_SRF_PERCALL_SETUP();
/* Get the next value from the input scan */
odesc = GPPC_SRF_RESULT_DESC();
idesc = GppcAnyTableGetTupleDesc(scan);
tuple = GppcAnyTableGetNextTuple(scan);
if (tuple == NULL)
GPPC_SRF_RETURN_DONE(fctx);
values[0] = GppcGetAttributeByNum(tuple, 1, &isnull[0]);
if (!isnull[0])
values[0] = GppcTextGetDatum(GppcCStringGetText(
strcat(colname, GppcTextGetCString(GppcDatumGetText(values[0])))));
result = GppcBuildHeapTupleDatum(odesc, values, isnull);
GPPC_SRF_RETURN_NEXT(fctx, result);
}
typedef struct MySession
{
GppcReportCallbackState cbstate;
char *message;
} MySession;
static void
tfcallback(GppcReportInfo info, void *arg)
{
GppcReportLevel elevel = GppcGetReportLevel(info);
if (elevel == GPPC_ERROR)
{
MySession *sess;
sess = (MySession *) arg;
GppcReport(GPPC_INFO, "message: %s", sess->message);
GppcFree(sess);
}
}
GPPC_FUNCTION_INFO(project_errorcallback);
GppcDatum project_errorcallback(GPPC_FUNCTION_ARGS);
GppcDatum project_errorcallback(GPPC_FUNCTION_ARGS)
{
GppcFuncCallContext fctx;
GppcAnyTable scan;
GppcTupleDesc odesc, idesc;
GppcHeapTuple tuple;
GppcDatum *values;
bool *isnull;
int i, attnum;
GppcDatum result;
scan = GPPC_GETARG_ANYTABLE(0);
if (GPPC_SRF_IS_FIRSTCALL())
{
MySession *sess;
fctx = GPPC_SRF_FIRSTCALL_INIT();
sess = (MySession *) GppcSRFAlloc(fctx, sizeof(MySession));
sess->cbstate = GppcInstallReportCallback(tfcallback, sess);
sess->message = GppcSRFAlloc(fctx, 255);
strcpy(sess->message, "Hello, world!");
/* Save session in the SRF context */
GppcSRFSave(fctx, sess);
}
fctx = GPPC_SRF_PERCALL_SETUP();
/*
* Return the input tuple as is, but it seems
* TableFunction doesn't accept tuples with <idesc>, so copy
* everything to a new tuple.
*/
odesc = GPPC_SRF_RESULT_DESC();
idesc = GppcAnyTableGetTupleDesc(scan);
tuple = GppcAnyTableGetNextTuple(scan);
if (tuple == NULL)
{
/* End of the input scan */
MySession *sess;
sess = (MySession *) GppcSRFRestore(fctx);
GppcUninstallReportCallback(sess->cbstate);
GppcFree(sess);
GPPC_SRF_RETURN_DONE(fctx);
}
attnum = GppcTupleDescNattrs(idesc);
values = GppcAlloc(sizeof(GppcDatum) * attnum);
isnull = GppcAlloc(sizeof(bool) * attnum);
for (i = 0; i < attnum; i++)
{
values[i] = GppcGetAttributeByNum(tuple, 1, &isnull[i]);
if (i == 0 && isnull[0])
GppcReport(GPPC_ERROR, "first attribute is NULL");
}
result = GppcBuildHeapTupleDatum(odesc, values, isnull);
GPPC_SRF_RETURN_NEXT(fctx, result);
}
#endif /* GP_VERSION_NUM >= 40200 */
GPPC_FUNCTION_INFO(test_encoding_name);
GppcDatum test_encoding_name(GPPC_FUNCTION_ARGS);
GppcDatum
test_encoding_name(GPPC_FUNCTION_ARGS)
{
GppcText res;
const char *str = GppcDatabaseEncodingName((GppcEncoding) GPPC_GETARG_INT4(0));
size_t len = strlen(str);
res = GppcAllocText(len);
memcpy(GppcGetTextPointer(res), str, len);
GPPC_RETURN_TEXT(res);
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦