如何在 PostgreSQL 16 中设置“VARSIZE”和“SET_VARSIZE”

问题描述 投票:0回答:1

我正在尝试在

mapnik-german-l10n
上构建
Ubuntu 22.04
但出现以下错误:

https://github.com/giggls/mapnik-german-l10n/blob/master/icutranslit/osml10n_translit.cpp

错误如下:

make -C icutranslit
make[1]: Entering directory '/home/test/mapnik-german-l10n-master/icutranslit'
g++ -fpic -fno-exceptions -I/usr/include/postgresql/16/server -c osml10n_translit.cpp
osml10n_translit.cpp: In function ‘Datum osml10n_translit(FunctionCallInfo)’:
osml10n_translit.cpp:46:26: error: ‘VARSIZE’ was not declared in this scope
   46 |   inbuf=(char *) malloc((VARSIZE(t) - VARHDRSZ +1)*sizeof(char));
      |                          ^~~~~~~
osml10n_translit.cpp:47:26: error: ‘VARDATA’ was not declared in this scope
   47 |   memcpy(inbuf, (void *) VARDATA(t), VARSIZE(t) - VARHDRSZ);
      |                          ^~~~~~~
osml10n_translit.cpp:72:3: error: ‘SET_VARSIZE’ was not declared in this scope
   72 |   SET_VARSIZE(new_text, VARHDRSZ + bufLen);
      |   ^~~~~~~~~~~
make[1]: *** [Makefile:13: osml10n_translit.o] Error 1
make[1]: Leaving directory '/home/test/mapnik-german-l10n-master/icutranslit'
make: *** [Makefile:30: icutranslit] Error 2

这是源代码:

/* needed in icu >= 62 */
#define U_USING_ICU_NAMESPACE 1

#include <iostream>
#include <unicode/unistr.h>
#include <unicode/translit.h>

extern "C" {

#include <postgres.h>
#include <stdlib.h>
#include <string.h>
#include <mb/pg_wchar.h>
#include <fmgr.h>

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(osml10n_translit);

Datum osml10n_translit(PG_FUNCTION_ARGS) {
  Transliterator *latin_tl;
  UErrorCode status = U_ZERO_ERROR;
  char *inbuf,*outbuf;
  
  if (GetDatabaseEncoding() != PG_UTF8) {
    ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
    errmsg("requires UTF8 database encoding")));
  }
   
  text *t = PG_GETARG_TEXT_P(0);

  inbuf=(char *) malloc((VARSIZE(t) - VARHDRSZ +1)*sizeof(char));
  memcpy(inbuf, (void *) VARDATA(t), VARSIZE(t) - VARHDRSZ);
  inbuf[VARSIZE(t) - VARHDRSZ]='\0';
   
  UnicodeString ustr(inbuf);
  latin_tl = Transliterator::createInstance("Any-Latin", UTRANS_FORWARD, status);
  if (latin_tl == 0) {
    ereport(ERROR,(errcode(ERRCODE_SYSTEM_ERROR),
    errmsg("ERROR: Transliterator::createInstance() failed")));
    PG_RETURN_TEXT_P("");
  }
  latin_tl->transliterate(ustr);
  
  
  int32_t bufLen = 100;
  outbuf = (char *) malloc((bufLen + 1)*sizeof(char));
  status=U_ZERO_ERROR;
  bufLen = ustr.extract(outbuf,bufLen,NULL,status);
  if (status == U_BUFFER_OVERFLOW_ERROR) {
    status=U_ZERO_ERROR;
    outbuf = (char *) realloc(outbuf, bufLen + 1);
    bufLen = ustr.extract(outbuf,bufLen,NULL,status);
  }
  outbuf[bufLen] = '\0'; 
  
  text *new_text = (text *) palloc(VARHDRSZ + bufLen);
  SET_VARSIZE(new_text, VARHDRSZ + bufLen);
  memcpy((void *) VARDATA(new_text), /* destination */
         (void *) outbuf,bufLen);
  
  free(inbuf);
  free(outbuf);
  delete latin_tl;       
  PG_RETURN_TEXT_P(new_text);
}

} /* extern "C" */

我尝试在

postgres.h
中搜索,但什么也没找到:

/usr/include/postgresql/16/server/postgres.h

哪个库包含这个“

VARSIZE
”和“
SET_VARSIZE
”?

更新:

我发现

/usr/include/postgresql/15/server/postgres.h
包含“
VARSIZE
”和“
SET_VARSIZE
”,但
/usr/include/postgresql/16/server/postgres.h
不包含。

这里是/usr/include/postgresql/15/server/postgres.h的源代码

/* ----------------------------------------------------------------
 *              Section 1:  variable-length datatypes (TOAST support)
 * ----------------------------------------------------------------
 */
...
/*
 * In consumers oblivious to data alignment, call PG_DETOAST_DATUM_PACKED(),
 * VARDATA_ANY(), VARSIZE_ANY() and VARSIZE_ANY_EXHDR().  Elsewhere, call
 * PG_DETOAST_DATUM(), VARDATA() and VARSIZE().  Directly fetching an int16,
 * int32 or wider field in the struct representing the datum layout requires
 * aligned data.  memcpy() is alignment-oblivious, as are most operations on
 * datatypes, such as text, whose layout struct contains only char fields.
 *
 * Code assembling a new datum should call VARDATA() and SET_VARSIZE().
 * (Datums begin life untoasted.)
 *
 * Other macros here should usually be used only by tuple assembly/disassembly
 * code and code that specifically wants to work with still-toasted Datums.
 */
#define VARDATA(PTR)                        VARDATA_4B(PTR)
#define VARSIZE(PTR)                        VARSIZE_4B(PTR)

#define VARSIZE_SHORT(PTR)                  VARSIZE_1B(PTR)
#define VARDATA_SHORT(PTR)                  VARDATA_1B(PTR)

#define VARTAG_EXTERNAL(PTR)                VARTAG_1B_E(PTR)
#define VARSIZE_EXTERNAL(PTR)               (VARHDRSZ_EXTERNAL + VARTAG_SIZE(VARTAG_EXTERNAL(PTR)))
#define VARDATA_EXTERNAL(PTR)               VARDATA_1B_E(PTR)
...

/* ----------------------------------------------------------------
 *              Section 2:  Datum type + support macros
 * ----------------------------------------------------------------
 */
...
typedef uintptr_t Datum;

/*
 * A NullableDatum is used in places where both a Datum and its nullness needs
 * to be stored. This can be more efficient than storing datums and nullness
 * in separate arrays, due to better spatial locality, even if more space may
 * be wasted due to padding.
 */
typedef struct NullableDatum
{
#define FIELDNO_NULLABLE_DATUM_DATUM 0
    Datum       value;
#define FIELDNO_NULLABLE_DATUM_ISNULL 1
    bool        isnull;
    /* due to alignment padding this could be used for flags for free */
} NullableDatum;
...

这里是/usr/include/postgresql/16/server/postgres.h的源代码

/* ----------------------------------------------------------------
 *              Section 1:  Datum type + support functions
 * ----------------------------------------------------------------
 */

/*
 * A Datum contains either a value of a pass-by-value type or a pointer to a
 * value of a pass-by-reference type.  Therefore, we require:
 *
 * sizeof(Datum) == sizeof(void *) == 4 or 8
 *
 * The functions below and the analogous functions for other types should be used to
 * convert between a Datum and the appropriate C type.
 */

typedef uintptr_t Datum;

/*
 * A NullableDatum is used in places where both a Datum and its nullness needs
 * to be stored. This can be more efficient than storing datums and nullness
 * in separate arrays, due to better spatial locality, even if more space may
 * be wasted due to padding.
 */
typedef struct NullableDatum
{
#define FIELDNO_NULLABLE_DATUM_DATUM 0
    Datum       value;
#define FIELDNO_NULLABLE_DATUM_ISNULL 1
    bool        isnull;
    /* due to alignment padding this could be used for flags for free */
} NullableDatum;

看来“

postgresql 16
”已经从
Section 1: variable-length datatypes (TOAST support)
中删除了“
postgres.h
”。

如何在“

VARSIZE
”中设置“
SET_VARSIZE
”和“
osml10n_translit.cpp
”以使其在
postgresql 16
中工作?

postgresql ubuntu github makefile
1个回答
0
投票

PostgreSQL v16 将这些定义移至

commit d952373a98
中的 server/varatt.h。所以你必须

#include "varatt.h"

从 v16 开始获取这些宏。

© www.soinside.com 2019 - 2024. All rights reserved.