PostgreSQL Source Code  git master
tsearchcmds.c File Reference
#include "postgres.h"
#include <ctype.h>
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_config_map.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_ts_parser.h"
#include "catalog/pg_ts_template.h"
#include "catalog/pg_type.h"
#include "commands/alter.h"
#include "commands/defrem.h"
#include "commands/event_trigger.h"
#include "common/string.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "tsearch/ts_cache.h"
#include "tsearch/ts_utils.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
Include dependency graph for tsearchcmds.c:

Go to the source code of this file.

Functions

static void MakeConfigurationMapping (AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
 
static void DropConfigurationMapping (AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
 
static DefElembuildDefItem (const char *name, const char *val, bool was_quoted)
 
static Datum get_ts_parser_func (DefElem *defel, int attnum)
 
static ObjectAddress makeParserDependencies (HeapTuple tuple)
 
ObjectAddress DefineTSParser (List *names, List *parameters)
 
static ObjectAddress makeDictionaryDependencies (HeapTuple tuple)
 
static void verify_dictoptions (Oid tmplId, List *dictoptions)
 
ObjectAddress DefineTSDictionary (List *names, List *parameters)
 
ObjectAddress AlterTSDictionary (AlterTSDictionaryStmt *stmt)
 
static Datum get_ts_template_func (DefElem *defel, int attnum)
 
static ObjectAddress makeTSTemplateDependencies (HeapTuple tuple)
 
ObjectAddress DefineTSTemplate (List *names, List *parameters)
 
static HeapTuple GetTSConfigTuple (List *names)
 
static ObjectAddress makeConfigurationDependencies (HeapTuple tuple, bool removeOld, Relation mapRel)
 
ObjectAddress DefineTSConfiguration (List *names, List *parameters, ObjectAddress *copied)
 
void RemoveTSConfigurationById (Oid cfgId)
 
ObjectAddress AlterTSConfiguration (AlterTSConfigurationStmt *stmt)
 
static int * getTokenTypes (Oid prsId, List *tokennames)
 
textserialize_deflist (List *deflist)
 
Listdeserialize_deflist (Datum txt)
 

Function Documentation

◆ AlterTSConfiguration()

ObjectAddress AlterTSConfiguration ( AlterTSConfigurationStmt stmt)

Definition at line 1111 of file tsearchcmds.c.

References aclcheck_error(), ACLCHECK_NOT_OWNER, AlterTSConfigurationStmt::cfgname, AlterTSConfigurationStmt::dicts, DropConfigurationMapping(), ereport, errcode(), errmsg(), ERROR, GETSTRUCT, GetTSConfigTuple(), GetUserId(), HeapTupleIsValid, InvokeObjectPostAlterHook, makeConfigurationDependencies(), MakeConfigurationMapping(), NameListToString(), OBJECT_TSCONFIGURATION, ObjectAddressSet, pg_ts_config_ownercheck(), ReleaseSysCache(), RowExclusiveLock, table_close(), table_open(), and AlterTSConfigurationStmt::tokentype.

Referenced by ProcessUtilitySlow().

1112 {
1113  HeapTuple tup;
1114  Oid cfgId;
1115  Relation relMap;
1116  ObjectAddress address;
1117 
1118  /* Find the configuration */
1119  tup = GetTSConfigTuple(stmt->cfgname);
1120  if (!HeapTupleIsValid(tup))
1121  ereport(ERROR,
1122  (errcode(ERRCODE_UNDEFINED_OBJECT),
1123  errmsg("text search configuration \"%s\" does not exist",
1124  NameListToString(stmt->cfgname))));
1125 
1126  cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid;
1127 
1128  /* must be owner */
1129  if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
1131  NameListToString(stmt->cfgname));
1132 
1133  relMap = table_open(TSConfigMapRelationId, RowExclusiveLock);
1134 
1135  /* Add or drop mappings */
1136  if (stmt->dicts)
1137  MakeConfigurationMapping(stmt, tup, relMap);
1138  else if (stmt->tokentype)
1139  DropConfigurationMapping(stmt, tup, relMap);
1140 
1141  /* Update dependencies */
1142  makeConfigurationDependencies(tup, true, relMap);
1143 
1144  InvokeObjectPostAlterHook(TSConfigRelationId, cfgId, 0);
1145 
1146  ObjectAddressSet(address, TSConfigRelationId, cfgId);
1147 
1148  table_close(relMap, RowExclusiveLock);
1149 
1150  ReleaseSysCache(tup);
1151 
1152  return address;
1153 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
Oid GetUserId(void)
Definition: miscinit.c:450
bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
Definition: aclchk.c:4997
static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel)
Definition: tsearchcmds.c:808
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
Definition: tsearchcmds.c:1378
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
static HeapTuple GetTSConfigTuple(List *names)
Definition: tsearchcmds.c:783
char * NameListToString(List *names)
Definition: namespace.c:3102
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:824
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
Definition: tsearchcmds.c:1214

◆ AlterTSDictionary()

ObjectAddress AlterTSDictionary ( AlterTSDictionaryStmt stmt)

Definition at line 488 of file tsearchcmds.c.

References aclcheck_error(), ACLCHECK_NOT_OWNER, DefElem::arg, CatalogTupleUpdate(), DefElem::defname, deserialize_deflist(), AlterTSDictionaryStmt::dictname, elog, ERROR, foreach_delete_current, get_ts_dict_oid(), GETSTRUCT, GetUserId(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, lappend(), lfirst, NameListToString(), NIL, OBJECT_TSDICTIONARY, ObjectAddressSet, ObjectIdGetDatum, AlterTSDictionaryStmt::options, pg_ts_dict_ownercheck(), PointerGetDatum, RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), serialize_deflist(), SysCacheGetAttr(), HeapTupleData::t_self, table_close(), table_open(), TSDICTOID, and verify_dictoptions().

Referenced by ProcessUtilitySlow().

489 {
490  HeapTuple tup,
491  newtup;
492  Relation rel;
493  Oid dictId;
494  ListCell *pl;
495  List *dictoptions;
496  Datum opt;
497  bool isnull;
498  Datum repl_val[Natts_pg_ts_dict];
499  bool repl_null[Natts_pg_ts_dict];
500  bool repl_repl[Natts_pg_ts_dict];
501  ObjectAddress address;
502 
503  dictId = get_ts_dict_oid(stmt->dictname, false);
504 
505  rel = table_open(TSDictionaryRelationId, RowExclusiveLock);
506 
508 
509  if (!HeapTupleIsValid(tup))
510  elog(ERROR, "cache lookup failed for text search dictionary %u",
511  dictId);
512 
513  /* must be owner */
514  if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
516  NameListToString(stmt->dictname));
517 
518  /* deserialize the existing set of options */
519  opt = SysCacheGetAttr(TSDICTOID, tup,
520  Anum_pg_ts_dict_dictinitoption,
521  &isnull);
522  if (isnull)
523  dictoptions = NIL;
524  else
525  dictoptions = deserialize_deflist(opt);
526 
527  /*
528  * Modify the options list as per specified changes
529  */
530  foreach(pl, stmt->options)
531  {
532  DefElem *defel = (DefElem *) lfirst(pl);
533  ListCell *cell;
534 
535  /*
536  * Remove any matches ...
537  */
538  foreach(cell, dictoptions)
539  {
540  DefElem *oldel = (DefElem *) lfirst(cell);
541 
542  if (strcmp(oldel->defname, defel->defname) == 0)
543  dictoptions = foreach_delete_current(dictoptions, cell);
544  }
545 
546  /*
547  * and add new value if it's got one
548  */
549  if (defel->arg)
550  dictoptions = lappend(dictoptions, defel);
551  }
552 
553  /*
554  * Validate
555  */
556  verify_dictoptions(((Form_pg_ts_dict) GETSTRUCT(tup))->dicttemplate,
557  dictoptions);
558 
559  /*
560  * Looks good, update
561  */
562  memset(repl_val, 0, sizeof(repl_val));
563  memset(repl_null, false, sizeof(repl_null));
564  memset(repl_repl, false, sizeof(repl_repl));
565 
566  if (dictoptions)
567  repl_val[Anum_pg_ts_dict_dictinitoption - 1] =
568  PointerGetDatum(serialize_deflist(dictoptions));
569  else
570  repl_null[Anum_pg_ts_dict_dictinitoption - 1] = true;
571  repl_repl[Anum_pg_ts_dict_dictinitoption - 1] = true;
572 
573  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
574  repl_val, repl_null, repl_repl);
575 
576  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
577 
578  InvokeObjectPostAlterHook(TSDictionaryRelationId, dictId, 0);
579 
580  ObjectAddressSet(address, TSDictionaryRelationId, dictId);
581 
582  /*
583  * NOTE: because we only support altering the options, not the template,
584  * there is no need to update dependencies. This might have to change if
585  * the options ever reference inside-the-database objects.
586  */
587 
588  heap_freetuple(newtup);
589  ReleaseSysCache(tup);
590 
592 
593  return address;
594 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool pg_ts_dict_ownercheck(Oid dict_oid, Oid roleid)
Definition: aclchk.c:4970
#define RelationGetDescr(relation)
Definition: rel.h:482
Oid GetUserId(void)
Definition: miscinit.c:450
#define PointerGetDatum(X)
Definition: postgres.h:556
List * deserialize_deflist(Datum txt)
Definition: tsearchcmds.c:1512
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
#define foreach_delete_current(lst, cell)
Definition: pg_list.h:368
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2426
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
Node * arg
Definition: parsenodes.h:733
List * lappend(List *list, void *datum)
Definition: list.c:321
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
char * NameListToString(List *names)
Definition: namespace.c:3102
text * serialize_deflist(List *deflist)
Definition: tsearchcmds.c:1456
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
static void verify_dictoptions(Oid tmplId, List *dictoptions)
Definition: tsearchcmds.c:337
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define elog(elevel,...)
Definition: elog.h:214
char * defname
Definition: parsenodes.h:732
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
Definition: pg_list.h:50

◆ buildDefItem()

static DefElem * buildDefItem ( const char *  name,
const char *  val,
bool  was_quoted 
)
static

Definition at line 1725 of file tsearchcmds.c.

References makeDefElem(), makeFloat(), makeInteger(), makeString(), pstrdup(), and strtoint().

Referenced by deserialize_deflist().

1726 {
1727  /* If input was quoted, always emit as string */
1728  if (!was_quoted && val[0] != '\0')
1729  {
1730  int v;
1731  char *endptr;
1732 
1733  /* Try to parse as an integer */
1734  errno = 0;
1735  v = strtoint(val, &endptr, 10);
1736  if (errno == 0 && *endptr == '\0')
1737  return makeDefElem(pstrdup(name),
1738  (Node *) makeInteger(v),
1739  -1);
1740  /* Nope, how about as a float? */
1741  errno = 0;
1742  (void) strtod(val, &endptr);
1743  if (errno == 0 && *endptr == '\0')
1744  return makeDefElem(pstrdup(name),
1745  (Node *) makeFloat(pstrdup(val)),
1746  -1);
1747  }
1748  /* Just make it a string */
1749  return makeDefElem(pstrdup(name),
1750  (Node *) makeString(pstrdup(val)),
1751  -1);
1752 }
Value * makeString(char *str)
Definition: value.c:53
char * pstrdup(const char *in)
Definition: mcxt.c:1186
Definition: nodes.h:529
DefElem * makeDefElem(char *name, Node *arg, int location)
Definition: makefuncs.c:546
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition: string.c:50
Value * makeInteger(int i)
Definition: value.c:23
Value * makeFloat(char *numericStr)
Definition: value.c:38
const char * name
Definition: encode.c:561
long val
Definition: informix.c:664

◆ DefineTSConfiguration()

ObjectAddress DefineTSConfiguration ( List names,
List parameters,
ObjectAddress copied 
)

Definition at line 895 of file tsearchcmds.c.

References ACL_CREATE, aclcheck_error(), ACLCHECK_OK, BTEqualStrategyNumber, CatalogTupleInsert(), defGetQualifiedName(), DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, get_namespace_name(), get_ts_config_oid(), get_ts_parser_oid(), GetNewOidWithIndex(), GETSTRUCT, GetUserId(), heap_form_tuple(), heap_freetuple(), HeapTupleIsValid, InvalidOid, InvokeObjectPostCreateHook, lfirst, makeConfigurationDependencies(), NameGetDatum, namestrcpy(), OBJECT_SCHEMA, ObjectAddressSet, ObjectIdGetDatum, OidIsValid, pg_namespace_aclcheck(), QualifiedNameGetCreationNamespace(), RelationData::rd_att, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TSConfigMapIndexId, TSCONFIGOID, TSConfigOidIndexId, and values.

Referenced by ProcessUtilitySlow().

896 {
897  Relation cfgRel;
898  Relation mapRel = NULL;
899  HeapTuple tup;
900  Datum values[Natts_pg_ts_config];
901  bool nulls[Natts_pg_ts_config];
902  AclResult aclresult;
903  Oid namespaceoid;
904  char *cfgname;
905  NameData cname;
906  Oid sourceOid = InvalidOid;
907  Oid prsOid = InvalidOid;
908  Oid cfgOid;
909  ListCell *pl;
910  ObjectAddress address;
911 
912  /* Convert list of names to a name and namespace */
913  namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname);
914 
915  /* Check we have creation rights in target namespace */
916  aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
917  if (aclresult != ACLCHECK_OK)
918  aclcheck_error(aclresult, OBJECT_SCHEMA,
919  get_namespace_name(namespaceoid));
920 
921  /*
922  * loop over the definition list and extract the information we need.
923  */
924  foreach(pl, parameters)
925  {
926  DefElem *defel = (DefElem *) lfirst(pl);
927 
928  if (strcmp(defel->defname, "parser") == 0)
929  prsOid = get_ts_parser_oid(defGetQualifiedName(defel), false);
930  else if (strcmp(defel->defname, "copy") == 0)
931  sourceOid = get_ts_config_oid(defGetQualifiedName(defel), false);
932  else
933  ereport(ERROR,
934  (errcode(ERRCODE_SYNTAX_ERROR),
935  errmsg("text search configuration parameter \"%s\" not recognized",
936  defel->defname)));
937  }
938 
939  if (OidIsValid(sourceOid) && OidIsValid(prsOid))
940  ereport(ERROR,
941  (errcode(ERRCODE_SYNTAX_ERROR),
942  errmsg("cannot specify both PARSER and COPY options")));
943 
944  /* make copied tsconfig available to callers */
945  if (copied && OidIsValid(sourceOid))
946  {
947  ObjectAddressSet(*copied,
948  TSConfigRelationId,
949  sourceOid);
950  }
951 
952  /*
953  * Look up source config if given.
954  */
955  if (OidIsValid(sourceOid))
956  {
957  Form_pg_ts_config cfg;
958 
959  tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(sourceOid));
960  if (!HeapTupleIsValid(tup))
961  elog(ERROR, "cache lookup failed for text search configuration %u",
962  sourceOid);
963 
964  cfg = (Form_pg_ts_config) GETSTRUCT(tup);
965 
966  /* use source's parser */
967  prsOid = cfg->cfgparser;
968 
969  ReleaseSysCache(tup);
970  }
971 
972  /*
973  * Validation
974  */
975  if (!OidIsValid(prsOid))
976  ereport(ERROR,
977  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
978  errmsg("text search parser is required")));
979 
980  cfgRel = table_open(TSConfigRelationId, RowExclusiveLock);
981 
982  /*
983  * Looks good, build tuple and insert
984  */
985  memset(values, 0, sizeof(values));
986  memset(nulls, false, sizeof(nulls));
987 
988  cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId,
989  Anum_pg_ts_config_oid);
990  values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
991  namestrcpy(&cname, cfgname);
992  values[Anum_pg_ts_config_cfgname - 1] = NameGetDatum(&cname);
993  values[Anum_pg_ts_config_cfgnamespace - 1] = ObjectIdGetDatum(namespaceoid);
994  values[Anum_pg_ts_config_cfgowner - 1] = ObjectIdGetDatum(GetUserId());
995  values[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(prsOid);
996 
997  tup = heap_form_tuple(cfgRel->rd_att, values, nulls);
998 
999  CatalogTupleInsert(cfgRel, tup);
1000 
1001  if (OidIsValid(sourceOid))
1002  {
1003  /*
1004  * Copy token-dicts map from source config
1005  */
1006  ScanKeyData skey;
1007  SysScanDesc scan;
1008  HeapTuple maptup;
1009 
1010  mapRel = table_open(TSConfigMapRelationId, RowExclusiveLock);
1011 
1012  ScanKeyInit(&skey,
1013  Anum_pg_ts_config_map_mapcfg,
1014  BTEqualStrategyNumber, F_OIDEQ,
1015  ObjectIdGetDatum(sourceOid));
1016 
1017  scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
1018  NULL, 1, &skey);
1019 
1020  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1021  {
1023  HeapTuple newmaptup;
1024  Datum mapvalues[Natts_pg_ts_config_map];
1025  bool mapnulls[Natts_pg_ts_config_map];
1026 
1027  memset(mapvalues, 0, sizeof(mapvalues));
1028  memset(mapnulls, false, sizeof(mapnulls));
1029 
1030  mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
1031  mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
1032  mapvalues[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
1033  mapvalues[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
1034 
1035  newmaptup = heap_form_tuple(mapRel->rd_att, mapvalues, mapnulls);
1036 
1037  CatalogTupleInsert(mapRel, newmaptup);
1038 
1039  heap_freetuple(newmaptup);
1040  }
1041 
1042  systable_endscan(scan);
1043  }
1044 
1045  address = makeConfigurationDependencies(tup, false, mapRel);
1046 
1047  /* Post creation hook for new text search configuration */
1048  InvokeObjectPostCreateHook(TSConfigRelationId, cfgOid, 0);
1049 
1050  heap_freetuple(tup);
1051 
1052  if (mapRel)
1053  table_close(mapRel, RowExclusiveLock);
1054  table_close(cfgRel, RowExclusiveLock);
1055 
1056  return address;
1057 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:317
#define NameGetDatum(X)
Definition: postgres.h:595
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:151
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
Oid GetUserId(void)
Definition: miscinit.c:450
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2995
FormData_pg_ts_config_map * Form_pg_ts_config_map
static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel)
Definition: tsearchcmds.c:808
int errcode(int sqlerrcode)
Definition: elog.c:610
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2679
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:651
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
Definition: c.h:616
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define RowExclusiveLock
Definition: lockdefs.h:38
#define TSConfigOidIndexId
Definition: indexing.h:270
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
AclResult
Definition: acl.h:177
uintptr_t Datum
Definition: postgres.h:367
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
TupleDesc rd_att
Definition: rel.h:110
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
Oid get_ts_parser_oid(List *names, bool missing_ok)
Definition: namespace.c:2300
#define lfirst(lc)
Definition: pg_list.h:190
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:273
char * defname
Definition: parsenodes.h:732
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ DefineTSDictionary()

ObjectAddress DefineTSDictionary ( List names,
List parameters 
)

Definition at line 392 of file tsearchcmds.c.

References ACL_CREATE, aclcheck_error(), ACLCHECK_OK, CatalogTupleInsert(), defGetQualifiedName(), DefElem::defname, ereport, errcode(), errmsg(), ERROR, get_namespace_name(), get_ts_template_oid(), GetNewOidWithIndex(), GetUserId(), heap_form_tuple(), heap_freetuple(), InvalidOid, InvokeObjectPostCreateHook, lappend(), lfirst, makeDictionaryDependencies(), NameGetDatum, namestrcpy(), NIL, OBJECT_SCHEMA, ObjectIdGetDatum, OidIsValid, pg_namespace_aclcheck(), PointerGetDatum, QualifiedNameGetCreationNamespace(), RelationData::rd_att, RowExclusiveLock, serialize_deflist(), table_close(), table_open(), TSDictionaryOidIndexId, values, and verify_dictoptions().

Referenced by ProcessUtilitySlow().

393 {
394  ListCell *pl;
395  Relation dictRel;
396  HeapTuple tup;
397  Datum values[Natts_pg_ts_dict];
398  bool nulls[Natts_pg_ts_dict];
399  NameData dname;
400  Oid templId = InvalidOid;
401  List *dictoptions = NIL;
402  Oid dictOid;
403  Oid namespaceoid;
404  AclResult aclresult;
405  char *dictname;
406  ObjectAddress address;
407 
408  /* Convert list of names to a name and namespace */
409  namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname);
410 
411  /* Check we have creation rights in target namespace */
412  aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
413  if (aclresult != ACLCHECK_OK)
414  aclcheck_error(aclresult, OBJECT_SCHEMA,
415  get_namespace_name(namespaceoid));
416 
417  /*
418  * loop over the definition list and extract the information we need.
419  */
420  foreach(pl, parameters)
421  {
422  DefElem *defel = (DefElem *) lfirst(pl);
423 
424  if (strcmp(defel->defname, "template") == 0)
425  {
426  templId = get_ts_template_oid(defGetQualifiedName(defel), false);
427  }
428  else
429  {
430  /* Assume it's an option for the dictionary itself */
431  dictoptions = lappend(dictoptions, defel);
432  }
433  }
434 
435  /*
436  * Validation
437  */
438  if (!OidIsValid(templId))
439  ereport(ERROR,
440  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
441  errmsg("text search template is required")));
442 
443  verify_dictoptions(templId, dictoptions);
444 
445 
446  dictRel = table_open(TSDictionaryRelationId, RowExclusiveLock);
447 
448  /*
449  * Looks good, insert
450  */
451  memset(values, 0, sizeof(values));
452  memset(nulls, false, sizeof(nulls));
453 
454  dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId,
455  Anum_pg_ts_dict_oid);
456  values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
457  namestrcpy(&dname, dictname);
458  values[Anum_pg_ts_dict_dictname - 1] = NameGetDatum(&dname);
459  values[Anum_pg_ts_dict_dictnamespace - 1] = ObjectIdGetDatum(namespaceoid);
460  values[Anum_pg_ts_dict_dictowner - 1] = ObjectIdGetDatum(GetUserId());
461  values[Anum_pg_ts_dict_dicttemplate - 1] = ObjectIdGetDatum(templId);
462  if (dictoptions)
463  values[Anum_pg_ts_dict_dictinitoption - 1] =
464  PointerGetDatum(serialize_deflist(dictoptions));
465  else
466  nulls[Anum_pg_ts_dict_dictinitoption - 1] = true;
467 
468  tup = heap_form_tuple(dictRel->rd_att, values, nulls);
469 
470  CatalogTupleInsert(dictRel, tup);
471 
472  address = makeDictionaryDependencies(tup);
473 
474  /* Post creation hook for new text search dictionary */
475  InvokeObjectPostCreateHook(TSDictionaryRelationId, dictOid, 0);
476 
477  heap_freetuple(tup);
478 
479  table_close(dictRel, RowExclusiveLock);
480 
481  return address;
482 }
#define NIL
Definition: pg_list.h:65
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:317
#define NameGetDatum(X)
Definition: postgres.h:595
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:151
Oid GetUserId(void)
Definition: miscinit.c:450
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2995
#define PointerGetDatum(X)
Definition: postgres.h:556
int errcode(int sqlerrcode)
Definition: elog.c:610
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:651
static ObjectAddress makeDictionaryDependencies(HeapTuple tuple)
Definition: tsearchcmds.c:302
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4625
#define TSDictionaryOidIndexId
Definition: indexing.h:278
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3294
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
Definition: c.h:616
Oid get_ts_template_oid(List *names, bool missing_ok)
Definition: namespace.c:2553
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define RowExclusiveLock
Definition: lockdefs.h:38
List * lappend(List *list, void *datum)
Definition: list.c:321
AclResult
Definition: acl.h:177
text * serialize_deflist(List *deflist)
Definition: tsearchcmds.c:1456
uintptr_t Datum
Definition: postgres.h:367
TupleDesc rd_att
Definition: rel.h:110
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define lfirst(lc)
Definition: pg_list.h:190
static void verify_dictoptions(Oid tmplId, List *dictoptions)
Definition: tsearchcmds.c:337
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:824
char * defname
Definition: parsenodes.h:732
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221

◆ DefineTSParser()

ObjectAddress DefineTSParser ( List names,
List parameters 
)

Definition at line 179 of file tsearchcmds.c.

References CatalogTupleInsert(), DatumGetObjectId, DefElem::defname, ereport, errcode(), errmsg(), ERROR, get_ts_parser_func(), GetNewOidWithIndex(), heap_form_tuple(), heap_freetuple(), InvokeObjectPostCreateHook, lfirst, makeParserDependencies(), NameGetDatum, namestrcpy(), ObjectIdGetDatum, OidIsValid, QualifiedNameGetCreationNamespace(), RelationData::rd_att, RowExclusiveLock, superuser(), table_close(), table_open(), TSParserOidIndexId, and values.

Referenced by ProcessUtilitySlow().

180 {
181  char *prsname;
182  ListCell *pl;
183  Relation prsRel;
184  HeapTuple tup;
185  Datum values[Natts_pg_ts_parser];
186  bool nulls[Natts_pg_ts_parser];
187  NameData pname;
188  Oid prsOid;
189  Oid namespaceoid;
190  ObjectAddress address;
191 
192  if (!superuser())
193  ereport(ERROR,
194  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
195  errmsg("must be superuser to create text search parsers")));
196 
197  prsRel = table_open(TSParserRelationId, RowExclusiveLock);
198 
199  /* Convert list of names to a name and namespace */
200  namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
201 
202  /* initialize tuple fields with name/namespace */
203  memset(values, 0, sizeof(values));
204  memset(nulls, false, sizeof(nulls));
205 
206  prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId,
207  Anum_pg_ts_parser_oid);
208  values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid);
209  namestrcpy(&pname, prsname);
210  values[Anum_pg_ts_parser_prsname - 1] = NameGetDatum(&pname);
211  values[Anum_pg_ts_parser_prsnamespace - 1] = ObjectIdGetDatum(namespaceoid);
212 
213  /*
214  * loop over the definition list and extract the information we need.
215  */
216  foreach(pl, parameters)
217  {
218  DefElem *defel = (DefElem *) lfirst(pl);
219 
220  if (strcmp(defel->defname, "start") == 0)
221  {
222  values[Anum_pg_ts_parser_prsstart - 1] =
223  get_ts_parser_func(defel, Anum_pg_ts_parser_prsstart);
224  }
225  else if (strcmp(defel->defname, "gettoken") == 0)
226  {
227  values[Anum_pg_ts_parser_prstoken - 1] =
228  get_ts_parser_func(defel, Anum_pg_ts_parser_prstoken);
229  }
230  else if (strcmp(defel->defname, "end") == 0)
231  {
232  values[Anum_pg_ts_parser_prsend - 1] =
233  get_ts_parser_func(defel, Anum_pg_ts_parser_prsend);
234  }
235  else if (strcmp(defel->defname, "headline") == 0)
236  {
237  values[Anum_pg_ts_parser_prsheadline - 1] =
238  get_ts_parser_func(defel, Anum_pg_ts_parser_prsheadline);
239  }
240  else if (strcmp(defel->defname, "lextypes") == 0)
241  {
242  values[Anum_pg_ts_parser_prslextype - 1] =
243  get_ts_parser_func(defel, Anum_pg_ts_parser_prslextype);
244  }
245  else
246  ereport(ERROR,
247  (errcode(ERRCODE_SYNTAX_ERROR),
248  errmsg("text search parser parameter \"%s\" not recognized",
249  defel->defname)));
250  }
251 
252  /*
253  * Validation
254  */
255  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prsstart - 1])))
256  ereport(ERROR,
257  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
258  errmsg("text search parser start method is required")));
259 
260  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prstoken - 1])))
261  ereport(ERROR,
262  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
263  errmsg("text search parser gettoken method is required")));
264 
265  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prsend - 1])))
266  ereport(ERROR,
267  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
268  errmsg("text search parser end method is required")));
269 
270  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_parser_prslextype - 1])))
271  ereport(ERROR,
272  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
273  errmsg("text search parser lextypes method is required")));
274 
275  /*
276  * Looks good, insert
277  */
278  tup = heap_form_tuple(prsRel->rd_att, values, nulls);
279 
280  CatalogTupleInsert(prsRel, tup);
281 
282  address = makeParserDependencies(tup);
283 
284  /* Post creation hook for new text search parser */
285  InvokeObjectPostCreateHook(TSParserRelationId, prsOid, 0);
286 
287  heap_freetuple(tup);
288 
289  table_close(prsRel, RowExclusiveLock);
290 
291  return address;
292 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:317
#define NameGetDatum(X)
Definition: postgres.h:595
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:151
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2995
#define DatumGetObjectId(X)
Definition: postgres.h:500
int errcode(int sqlerrcode)
Definition: elog.c:610
bool superuser(void)
Definition: superuser.c:46
static ObjectAddress makeParserDependencies(HeapTuple tuple)
Definition: tsearchcmds.c:131
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:651
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Definition: c.h:616
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:367
TupleDesc rd_att
Definition: rel.h:110
#define ereport(elevel,...)
Definition: elog.h:144
#define lfirst(lc)
Definition: pg_list.h:190
static Datum get_ts_parser_func(DefElem *defel, int attnum)
Definition: tsearchcmds.c:68
#define TSParserOidIndexId
Definition: indexing.h:283
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:824
char * defname
Definition: parsenodes.h:732
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221

◆ DefineTSTemplate()

ObjectAddress DefineTSTemplate ( List names,
List parameters 
)

Definition at line 686 of file tsearchcmds.c.

References CatalogTupleInsert(), DatumGetObjectId, DefElem::defname, ereport, errcode(), errmsg(), ERROR, get_ts_template_func(), GetNewOidWithIndex(), heap_form_tuple(), heap_freetuple(), i, InvalidOid, InvokeObjectPostCreateHook, lfirst, makeTSTemplateDependencies(), NameGetDatum, namestrcpy(), ObjectIdGetDatum, OidIsValid, QualifiedNameGetCreationNamespace(), RelationData::rd_att, RowExclusiveLock, superuser(), table_close(), table_open(), TSTemplateOidIndexId, and values.

Referenced by ProcessUtilitySlow().

687 {
688  ListCell *pl;
689  Relation tmplRel;
690  HeapTuple tup;
691  Datum values[Natts_pg_ts_template];
692  bool nulls[Natts_pg_ts_template];
693  NameData dname;
694  int i;
695  Oid tmplOid;
696  Oid namespaceoid;
697  char *tmplname;
698  ObjectAddress address;
699 
700  if (!superuser())
701  ereport(ERROR,
702  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
703  errmsg("must be superuser to create text search templates")));
704 
705  /* Convert list of names to a name and namespace */
706  namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname);
707 
708  tmplRel = table_open(TSTemplateRelationId, RowExclusiveLock);
709 
710  for (i = 0; i < Natts_pg_ts_template; i++)
711  {
712  nulls[i] = false;
713  values[i] = ObjectIdGetDatum(InvalidOid);
714  }
715 
716  tmplOid = GetNewOidWithIndex(tmplRel, TSTemplateOidIndexId,
717  Anum_pg_ts_dict_oid);
718  values[Anum_pg_ts_template_oid - 1] = ObjectIdGetDatum(tmplOid);
719  namestrcpy(&dname, tmplname);
720  values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname);
721  values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid);
722 
723  /*
724  * loop over the definition list and extract the information we need.
725  */
726  foreach(pl, parameters)
727  {
728  DefElem *defel = (DefElem *) lfirst(pl);
729 
730  if (strcmp(defel->defname, "init") == 0)
731  {
732  values[Anum_pg_ts_template_tmplinit - 1] =
733  get_ts_template_func(defel, Anum_pg_ts_template_tmplinit);
734  nulls[Anum_pg_ts_template_tmplinit - 1] = false;
735  }
736  else if (strcmp(defel->defname, "lexize") == 0)
737  {
738  values[Anum_pg_ts_template_tmpllexize - 1] =
739  get_ts_template_func(defel, Anum_pg_ts_template_tmpllexize);
740  nulls[Anum_pg_ts_template_tmpllexize - 1] = false;
741  }
742  else
743  ereport(ERROR,
744  (errcode(ERRCODE_SYNTAX_ERROR),
745  errmsg("text search template parameter \"%s\" not recognized",
746  defel->defname)));
747  }
748 
749  /*
750  * Validation
751  */
752  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_template_tmpllexize - 1])))
753  ereport(ERROR,
754  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
755  errmsg("text search template lexize method is required")));
756 
757  /*
758  * Looks good, insert
759  */
760  tup = heap_form_tuple(tmplRel->rd_att, values, nulls);
761 
762  CatalogTupleInsert(tmplRel, tup);
763 
764  address = makeTSTemplateDependencies(tup);
765 
766  /* Post creation hook for new text search template */
767  InvokeObjectPostCreateHook(TSTemplateRelationId, tmplOid, 0);
768 
769  heap_freetuple(tup);
770 
771  table_close(tmplRel, RowExclusiveLock);
772 
773  return address;
774 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:317
#define NameGetDatum(X)
Definition: postgres.h:595
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define InvokeObjectPostCreateHook(classId, objectId, subId)
Definition: objectaccess.h:151
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2995
#define DatumGetObjectId(X)
Definition: postgres.h:500
static Datum get_ts_template_func(DefElem *defel, int attnum)
Definition: tsearchcmds.c:604
int errcode(int sqlerrcode)
Definition: elog.c:610
bool superuser(void)
Definition: superuser.c:46
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:651
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Definition: c.h:616
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:367
TupleDesc rd_att
Definition: rel.h:110
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
static ObjectAddress makeTSTemplateDependencies(HeapTuple tuple)
Definition: tsearchcmds.c:647
#define lfirst(lc)
Definition: pg_list.h:190
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
char * defname
Definition: parsenodes.h:732
#define TSTemplateOidIndexId
Definition: indexing.h:288
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221

◆ deserialize_deflist()

List* deserialize_deflist ( Datum  txt)

Definition at line 1512 of file tsearchcmds.c.

References buildDefItem(), DatumGetTextPP, elog, ereport, errcode(), errmsg(), ERROR, lappend(), NIL, palloc(), pfree(), text_to_cstring(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by AlterTSDictionary(), lookup_ts_dictionary_cache(), ts_headline_byid_opt(), ts_headline_json_byid_opt(), and ts_headline_jsonb_byid_opt().

1513 {
1514  text *in = DatumGetTextPP(txt); /* in case it's toasted */
1515  List *result = NIL;
1516  int len = VARSIZE_ANY_EXHDR(in);
1517  char *ptr,
1518  *endptr,
1519  *workspace,
1520  *wsptr = NULL,
1521  *startvalue = NULL;
1522  typedef enum
1523  {
1524  CS_WAITKEY,
1525  CS_INKEY,
1526  CS_INQKEY,
1527  CS_WAITEQ,
1528  CS_WAITVALUE,
1529  CS_INSQVALUE,
1530  CS_INDQVALUE,
1531  CS_INWVALUE
1532  } ds_state;
1533  ds_state state = CS_WAITKEY;
1534 
1535  workspace = (char *) palloc(len + 1); /* certainly enough room */
1536  ptr = VARDATA_ANY(in);
1537  endptr = ptr + len;
1538  for (; ptr < endptr; ptr++)
1539  {
1540  switch (state)
1541  {
1542  case CS_WAITKEY:
1543  if (isspace((unsigned char) *ptr) || *ptr == ',')
1544  continue;
1545  if (*ptr == '"')
1546  {
1547  wsptr = workspace;
1548  state = CS_INQKEY;
1549  }
1550  else
1551  {
1552  wsptr = workspace;
1553  *wsptr++ = *ptr;
1554  state = CS_INKEY;
1555  }
1556  break;
1557  case CS_INKEY:
1558  if (isspace((unsigned char) *ptr))
1559  {
1560  *wsptr++ = '\0';
1561  state = CS_WAITEQ;
1562  }
1563  else if (*ptr == '=')
1564  {
1565  *wsptr++ = '\0';
1566  state = CS_WAITVALUE;
1567  }
1568  else
1569  {
1570  *wsptr++ = *ptr;
1571  }
1572  break;
1573  case CS_INQKEY:
1574  if (*ptr == '"')
1575  {
1576  if (ptr + 1 < endptr && ptr[1] == '"')
1577  {
1578  /* copy only one of the two quotes */
1579  *wsptr++ = *ptr++;
1580  }
1581  else
1582  {
1583  *wsptr++ = '\0';
1584  state = CS_WAITEQ;
1585  }
1586  }
1587  else
1588  {
1589  *wsptr++ = *ptr;
1590  }
1591  break;
1592  case CS_WAITEQ:
1593  if (*ptr == '=')
1594  state = CS_WAITVALUE;
1595  else if (!isspace((unsigned char) *ptr))
1596  ereport(ERROR,
1597  (errcode(ERRCODE_SYNTAX_ERROR),
1598  errmsg("invalid parameter list format: \"%s\"",
1599  text_to_cstring(in))));
1600  break;
1601  case CS_WAITVALUE:
1602  if (*ptr == '\'')
1603  {
1604  startvalue = wsptr;
1605  state = CS_INSQVALUE;
1606  }
1607  else if (*ptr == 'E' && ptr + 1 < endptr && ptr[1] == '\'')
1608  {
1609  ptr++;
1610  startvalue = wsptr;
1611  state = CS_INSQVALUE;
1612  }
1613  else if (*ptr == '"')
1614  {
1615  startvalue = wsptr;
1616  state = CS_INDQVALUE;
1617  }
1618  else if (!isspace((unsigned char) *ptr))
1619  {
1620  startvalue = wsptr;
1621  *wsptr++ = *ptr;
1622  state = CS_INWVALUE;
1623  }
1624  break;
1625  case CS_INSQVALUE:
1626  if (*ptr == '\'')
1627  {
1628  if (ptr + 1 < endptr && ptr[1] == '\'')
1629  {
1630  /* copy only one of the two quotes */
1631  *wsptr++ = *ptr++;
1632  }
1633  else
1634  {
1635  *wsptr++ = '\0';
1636  result = lappend(result,
1637  buildDefItem(workspace,
1638  startvalue,
1639  true));
1640  state = CS_WAITKEY;
1641  }
1642  }
1643  else if (*ptr == '\\')
1644  {
1645  if (ptr + 1 < endptr && ptr[1] == '\\')
1646  {
1647  /* copy only one of the two backslashes */
1648  *wsptr++ = *ptr++;
1649  }
1650  else
1651  *wsptr++ = *ptr;
1652  }
1653  else
1654  {
1655  *wsptr++ = *ptr;
1656  }
1657  break;
1658  case CS_INDQVALUE:
1659  if (*ptr == '"')
1660  {
1661  if (ptr + 1 < endptr && ptr[1] == '"')
1662  {
1663  /* copy only one of the two quotes */
1664  *wsptr++ = *ptr++;
1665  }
1666  else
1667  {
1668  *wsptr++ = '\0';
1669  result = lappend(result,
1670  buildDefItem(workspace,
1671  startvalue,
1672  true));
1673  state = CS_WAITKEY;
1674  }
1675  }
1676  else
1677  {
1678  *wsptr++ = *ptr;
1679  }
1680  break;
1681  case CS_INWVALUE:
1682  if (*ptr == ',' || isspace((unsigned char) *ptr))
1683  {
1684  *wsptr++ = '\0';
1685  result = lappend(result,
1686  buildDefItem(workspace,
1687  startvalue,
1688  false));
1689  state = CS_WAITKEY;
1690  }
1691  else
1692  {
1693  *wsptr++ = *ptr;
1694  }
1695  break;
1696  default:
1697  elog(ERROR, "unrecognized deserialize_deflist state: %d",
1698  state);
1699  }
1700  }
1701 
1702  if (state == CS_INWVALUE)
1703  {
1704  *wsptr++ = '\0';
1705  result = lappend(result,
1706  buildDefItem(workspace,
1707  startvalue,
1708  false));
1709  }
1710  else if (state != CS_WAITKEY)
1711  ereport(ERROR,
1712  (errcode(ERRCODE_SYNTAX_ERROR),
1713  errmsg("invalid parameter list format: \"%s\"",
1714  text_to_cstring(in))));
1715 
1716  pfree(workspace);
1717 
1718  return result;
1719 }
#define NIL
Definition: pg_list.h:65
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
#define DatumGetTextPP(X)
Definition: fmgr.h:291
int errcode(int sqlerrcode)
Definition: elog.c:610
static DefElem * buildDefItem(const char *name, const char *val, bool was_quoted)
Definition: tsearchcmds.c:1725
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
List * lappend(List *list, void *datum)
Definition: list.c:321
#define ereport(elevel,...)
Definition: elog.h:144
Definition: regguts.h:298
char * text_to_cstring(const text *t)
Definition: varlena.c:205
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:341
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
Definition: c.h:562
Definition: pg_list.h:50

◆ DropConfigurationMapping()

static void DropConfigurationMapping ( AlterTSConfigurationStmt stmt,
HeapTuple  tup,
Relation  relMap 
)
static

Definition at line 1378 of file tsearchcmds.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), ereport, errcode(), errmsg(), ERROR, EventTriggerCollectAlterTSConfig(), GETSTRUCT, getTokenTypes(), HeapTupleIsValid, i, Int32GetDatum, lfirst, AlterTSConfigurationStmt::missing_ok, NOTICE, ObjectIdGetDatum, ScanKeyInit(), strVal, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, AlterTSConfigurationStmt::tokentype, TSConfigMapIndexId, and val.

Referenced by AlterTSConfiguration().

1380 {
1381  Form_pg_ts_config tsform;
1382  Oid cfgId;
1383  ScanKeyData skey[2];
1384  SysScanDesc scan;
1385  HeapTuple maptup;
1386  int i;
1387  Oid prsId;
1388  int *tokens;
1389  ListCell *c;
1390 
1391  tsform = (Form_pg_ts_config) GETSTRUCT(tup);
1392  cfgId = tsform->oid;
1393  prsId = tsform->cfgparser;
1394 
1395  tokens = getTokenTypes(prsId, stmt->tokentype);
1396 
1397  i = 0;
1398  foreach(c, stmt->tokentype)
1399  {
1400  Value *val = (Value *) lfirst(c);
1401  bool found = false;
1402 
1403  ScanKeyInit(&skey[0],
1404  Anum_pg_ts_config_map_mapcfg,
1405  BTEqualStrategyNumber, F_OIDEQ,
1406  ObjectIdGetDatum(cfgId));
1407  ScanKeyInit(&skey[1],
1408  Anum_pg_ts_config_map_maptokentype,
1409  BTEqualStrategyNumber, F_INT4EQ,
1410  Int32GetDatum(tokens[i]));
1411 
1412  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1413  NULL, 2, skey);
1414 
1415  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1416  {
1417  CatalogTupleDelete(relMap, &maptup->t_self);
1418  found = true;
1419  }
1420 
1421  systable_endscan(scan);
1422 
1423  if (!found)
1424  {
1425  if (!stmt->missing_ok)
1426  {
1427  ereport(ERROR,
1428  (errcode(ERRCODE_UNDEFINED_OBJECT),
1429  errmsg("mapping for token type \"%s\" does not exist",
1430  strVal(val))));
1431  }
1432  else
1433  {
1434  ereport(NOTICE,
1435  (errmsg("mapping for token type \"%s\" does not exist, skipping",
1436  strVal(val))));
1437  }
1438  }
1439 
1440  i++;
1441  }
1442 
1443  EventTriggerCollectAlterTSConfig(stmt, cfgId, NULL, 0);
1444 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
static int * getTokenTypes(Oid prsId, List *tokennames)
Definition: tsearchcmds.c:1159
char * c
void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId, Oid *dictIds, int ndicts)
#define ereport(elevel,...)
Definition: elog.h:144
#define NOTICE
Definition: elog.h:37
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
Definition: value.h:42
#define Int32GetDatum(X)
Definition: postgres.h:479
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:273
long val
Definition: informix.c:664
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_ts_parser_func()

static Datum get_ts_parser_func ( DefElem defel,
int  attnum 
)
static

Definition at line 68 of file tsearchcmds.c.

References defGetQualifiedName(), elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), func_signature_string(), get_func_rettype(), LookupFuncName(), NIL, and ObjectIdGetDatum.

Referenced by DefineTSParser().

69 {
70  List *funcName = defGetQualifiedName(defel);
71  Oid typeId[3];
72  Oid retTypeId;
73  int nargs;
74  Oid procOid;
75 
76  retTypeId = INTERNALOID; /* correct for most */
77  typeId[0] = INTERNALOID;
78  switch (attnum)
79  {
80  case Anum_pg_ts_parser_prsstart:
81  nargs = 2;
82  typeId[1] = INT4OID;
83  break;
84  case Anum_pg_ts_parser_prstoken:
85  nargs = 3;
86  typeId[1] = INTERNALOID;
87  typeId[2] = INTERNALOID;
88  break;
89  case Anum_pg_ts_parser_prsend:
90  nargs = 1;
91  retTypeId = VOIDOID;
92  break;
93  case Anum_pg_ts_parser_prsheadline:
94  nargs = 3;
95  typeId[1] = INTERNALOID;
96  typeId[2] = TSQUERYOID;
97  break;
98  case Anum_pg_ts_parser_prslextype:
99  nargs = 1;
100 
101  /*
102  * Note: because the lextype method returns type internal, it must
103  * have an internal-type argument for security reasons. The
104  * argument is not actually used, but is just passed as a zero.
105  */
106  break;
107  default:
108  /* should not be here */
109  elog(ERROR, "unrecognized attribute for text search parser: %d",
110  attnum);
111  nargs = 0; /* keep compiler quiet */
112  }
113 
114  procOid = LookupFuncName(funcName, nargs, typeId, false);
115  if (get_func_rettype(procOid) != retTypeId)
116  ereport(ERROR,
117  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
118  errmsg("function %s should return type %s",
119  func_signature_string(funcName, nargs, NIL, typeId),
120  format_type_be(retTypeId))));
121 
122  return ObjectIdGetDatum(procOid);
123 }
#define NIL
Definition: pg_list.h:65
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1567
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2103
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
Definition: parse_func.c:2015
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:144
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
Definition: pg_list.h:50

◆ get_ts_template_func()

static Datum get_ts_template_func ( DefElem defel,
int  attnum 
)
static

Definition at line 604 of file tsearchcmds.c.

References defGetQualifiedName(), elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), func_signature_string(), get_func_rettype(), LookupFuncName(), NIL, and ObjectIdGetDatum.

Referenced by DefineTSTemplate().

605 {
606  List *funcName = defGetQualifiedName(defel);
607  Oid typeId[4];
608  Oid retTypeId;
609  int nargs;
610  Oid procOid;
611 
612  retTypeId = INTERNALOID;
613  typeId[0] = INTERNALOID;
614  typeId[1] = INTERNALOID;
615  typeId[2] = INTERNALOID;
616  typeId[3] = INTERNALOID;
617  switch (attnum)
618  {
619  case Anum_pg_ts_template_tmplinit:
620  nargs = 1;
621  break;
622  case Anum_pg_ts_template_tmpllexize:
623  nargs = 4;
624  break;
625  default:
626  /* should not be here */
627  elog(ERROR, "unrecognized attribute for text search template: %d",
628  attnum);
629  nargs = 0; /* keep compiler quiet */
630  }
631 
632  procOid = LookupFuncName(funcName, nargs, typeId, false);
633  if (get_func_rettype(procOid) != retTypeId)
634  ereport(ERROR,
635  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
636  errmsg("function %s should return type %s",
637  func_signature_string(funcName, nargs, NIL, typeId),
638  format_type_be(retTypeId))));
639 
640  return ObjectIdGetDatum(procOid);
641 }
#define NIL
Definition: pg_list.h:65
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1567
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok)
Definition: parse_func.c:2103
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
Definition: parse_func.c:2015
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:144
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
Definition: pg_list.h:50

◆ getTokenTypes()

static int* getTokenTypes ( Oid  prsId,
List tokennames 
)
static

Definition at line 1159 of file tsearchcmds.c.

References LexDescr::alias, DatumGetPointer, elog, ereport, errcode(), errmsg(), ERROR, i, LexDescr::lexid, TSParserCacheEntry::lextypeOid, lfirst, sort-test::list, list_length(), lookup_ts_parser_cache(), OidFunctionCall1, OidIsValid, palloc(), strVal, and val.

Referenced by DropConfigurationMapping(), and MakeConfigurationMapping().

1160 {
1162  LexDescr *list;
1163  int *res,
1164  i,
1165  ntoken;
1166  ListCell *tn;
1167 
1168  ntoken = list_length(tokennames);
1169  if (ntoken == 0)
1170  return NULL;
1171  res = (int *) palloc(sizeof(int) * ntoken);
1172 
1173  if (!OidIsValid(prs->lextypeOid))
1174  elog(ERROR, "method lextype isn't defined for text search parser %u",
1175  prsId);
1176 
1177  /* lextype takes one dummy argument */
1179  (Datum) 0));
1180 
1181  i = 0;
1182  foreach(tn, tokennames)
1183  {
1184  Value *val = (Value *) lfirst(tn);
1185  bool found = false;
1186  int j;
1187 
1188  j = 0;
1189  while (list && list[j].lexid)
1190  {
1191  if (strcmp(strVal(val), list[j].alias) == 0)
1192  {
1193  res[i] = list[j].lexid;
1194  found = true;
1195  break;
1196  }
1197  j++;
1198  }
1199  if (!found)
1200  ereport(ERROR,
1201  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1202  errmsg("token type \"%s\" does not exist",
1203  strVal(val))));
1204  i++;
1205  }
1206 
1207  return res;
1208 }
char * alias
Definition: ts_public.h:28
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:610
TSParserCacheEntry * lookup_ts_parser_cache(Oid prsId)
Definition: ts_cache.c:112
#define OidIsValid(objectId)
Definition: c.h:651
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:662
int lexid
Definition: ts_public.h:27
uintptr_t Datum
Definition: postgres.h:367
#define ereport(elevel,...)
Definition: elog.h:144
#define lfirst(lc)
Definition: pg_list.h:190
Definition: value.h:42
static int list_length(const List *l)
Definition: pg_list.h:169
#define DatumGetPointer(X)
Definition: postgres.h:549
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
int i
long val
Definition: informix.c:664

◆ GetTSConfigTuple()

static HeapTuple GetTSConfigTuple ( List names)
static

Definition at line 783 of file tsearchcmds.c.

References elog, ERROR, get_ts_config_oid(), HeapTupleIsValid, ObjectIdGetDatum, OidIsValid, SearchSysCache1(), and TSCONFIGOID.

Referenced by AlterTSConfiguration().

784 {
785  HeapTuple tup;
786  Oid cfgId;
787 
788  cfgId = get_ts_config_oid(names, true);
789  if (!OidIsValid(cfgId))
790  return NULL;
791 
793 
794  if (!HeapTupleIsValid(tup)) /* should not happen */
795  elog(ERROR, "cache lookup failed for text search configuration %u",
796  cfgId);
797 
798  return tup;
799 }
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2679
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:651
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214

◆ makeConfigurationDependencies()

static ObjectAddress makeConfigurationDependencies ( HeapTuple  tuple,
bool  removeOld,
Relation  mapRel 
)
static

Definition at line 808 of file tsearchcmds.c.

References add_exact_object_address(), BTEqualStrategyNumber, ObjectAddress::classId, CommandCounterIncrement(), deleteDependencyRecordsFor(), deleteSharedDependencyRecordsFor(), DEPENDENCY_NORMAL, free_object_addresses(), GETSTRUCT, HeapTupleIsValid, new_object_addresses(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, record_object_address_dependencies(), recordDependencyOnCurrentExtension(), recordDependencyOnOwner(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and TSConfigMapIndexId.

Referenced by AlterTSConfiguration(), and DefineTSConfiguration().

810 {
812  ObjectAddresses *addrs;
813  ObjectAddress myself,
814  referenced;
815 
816  myself.classId = TSConfigRelationId;
817  myself.objectId = cfg->oid;
818  myself.objectSubId = 0;
819 
820  /* for ALTER case, first flush old dependencies, except extension deps */
821  if (removeOld)
822  {
823  deleteDependencyRecordsFor(myself.classId, myself.objectId, true);
825  }
826 
827  /*
828  * We use an ObjectAddresses list to remove possible duplicate
829  * dependencies from the config map info. The pg_ts_config items
830  * shouldn't be duplicates, but might as well fold them all into one call.
831  */
832  addrs = new_object_addresses();
833 
834  /* dependency on namespace */
835  referenced.classId = NamespaceRelationId;
836  referenced.objectId = cfg->cfgnamespace;
837  referenced.objectSubId = 0;
838  add_exact_object_address(&referenced, addrs);
839 
840  /* dependency on owner */
841  recordDependencyOnOwner(myself.classId, myself.objectId, cfg->cfgowner);
842 
843  /* dependency on extension */
844  recordDependencyOnCurrentExtension(&myself, removeOld);
845 
846  /* dependency on parser */
847  referenced.classId = TSParserRelationId;
848  referenced.objectId = cfg->cfgparser;
849  referenced.objectSubId = 0;
850  add_exact_object_address(&referenced, addrs);
851 
852  /* dependencies on dictionaries listed in config map */
853  if (mapRel)
854  {
855  ScanKeyData skey;
856  SysScanDesc scan;
857  HeapTuple maptup;
858 
859  /* CCI to ensure we can see effects of caller's changes */
861 
862  ScanKeyInit(&skey,
863  Anum_pg_ts_config_map_mapcfg,
864  BTEqualStrategyNumber, F_OIDEQ,
865  ObjectIdGetDatum(myself.objectId));
866 
867  scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
868  NULL, 1, &skey);
869 
870  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
871  {
873 
874  referenced.classId = TSDictionaryRelationId;
875  referenced.objectId = cfgmap->mapdict;
876  referenced.objectSubId = 0;
877  add_exact_object_address(&referenced, addrs);
878  }
879 
880  systable_endscan(scan);
881  }
882 
883  /* Record 'em (this includes duplicate elimination) */
885 
886  free_object_addresses(addrs);
887 
888  return myself;
889 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
FormData_pg_ts_config_map * Form_pg_ts_config_map
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
Definition: dependency.c:2676
long deleteDependencyRecordsFor(Oid classId, Oid objectId, bool skipExtensionDeps)
Definition: pg_depend.c:190
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2467
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:164
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2412
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2707
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
Definition: pg_shdepend.c:947
void CommandCounterIncrement(void)
Definition: xact.c:1021
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:138
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:273
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ MakeConfigurationMapping()

static void MakeConfigurationMapping ( AlterTSConfigurationStmt stmt,
HeapTuple  tup,
Relation  relMap 
)
static

Definition at line 1214 of file tsearchcmds.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), AlterTSConfigurationStmt::dicts, EventTriggerCollectAlterTSConfig(), get_ts_dict_oid(), GETSTRUCT, getTokenTypes(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, i, Int32GetDatum, lfirst, list_length(), ObjectIdGetDatum, AlterTSConfigurationStmt::override, palloc(), RelationData::rd_att, RelationGetDescr, AlterTSConfigurationStmt::replace, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, AlterTSConfigurationStmt::tokentype, TSConfigMapIndexId, and values.

Referenced by AlterTSConfiguration().

1216 {
1217  Form_pg_ts_config tsform;
1218  Oid cfgId;
1219  ScanKeyData skey[2];
1220  SysScanDesc scan;
1221  HeapTuple maptup;
1222  int i;
1223  int j;
1224  Oid prsId;
1225  int *tokens,
1226  ntoken;
1227  Oid *dictIds;
1228  int ndict;
1229  ListCell *c;
1230 
1231  tsform = (Form_pg_ts_config) GETSTRUCT(tup);
1232  cfgId = tsform->oid;
1233  prsId = tsform->cfgparser;
1234 
1235  tokens = getTokenTypes(prsId, stmt->tokentype);
1236  ntoken = list_length(stmt->tokentype);
1237 
1238  if (stmt->override)
1239  {
1240  /*
1241  * delete maps for tokens if they exist and command was ALTER
1242  */
1243  for (i = 0; i < ntoken; i++)
1244  {
1245  ScanKeyInit(&skey[0],
1246  Anum_pg_ts_config_map_mapcfg,
1247  BTEqualStrategyNumber, F_OIDEQ,
1248  ObjectIdGetDatum(cfgId));
1249  ScanKeyInit(&skey[1],
1250  Anum_pg_ts_config_map_maptokentype,
1251  BTEqualStrategyNumber, F_INT4EQ,
1252  Int32GetDatum(tokens[i]));
1253 
1254  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1255  NULL, 2, skey);
1256 
1257  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1258  {
1259  CatalogTupleDelete(relMap, &maptup->t_self);
1260  }
1261 
1262  systable_endscan(scan);
1263  }
1264  }
1265 
1266  /*
1267  * Convert list of dictionary names to array of dict OIDs
1268  */
1269  ndict = list_length(stmt->dicts);
1270  dictIds = (Oid *) palloc(sizeof(Oid) * ndict);
1271  i = 0;
1272  foreach(c, stmt->dicts)
1273  {
1274  List *names = (List *) lfirst(c);
1275 
1276  dictIds[i] = get_ts_dict_oid(names, false);
1277  i++;
1278  }
1279 
1280  if (stmt->replace)
1281  {
1282  /*
1283  * Replace a specific dictionary in existing entries
1284  */
1285  Oid dictOld = dictIds[0],
1286  dictNew = dictIds[1];
1287 
1288  ScanKeyInit(&skey[0],
1289  Anum_pg_ts_config_map_mapcfg,
1290  BTEqualStrategyNumber, F_OIDEQ,
1291  ObjectIdGetDatum(cfgId));
1292 
1293  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1294  NULL, 1, skey);
1295 
1296  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1297  {
1299 
1300  /*
1301  * check if it's one of target token types
1302  */
1303  if (tokens)
1304  {
1305  bool tokmatch = false;
1306 
1307  for (j = 0; j < ntoken; j++)
1308  {
1309  if (cfgmap->maptokentype == tokens[j])
1310  {
1311  tokmatch = true;
1312  break;
1313  }
1314  }
1315  if (!tokmatch)
1316  continue;
1317  }
1318 
1319  /*
1320  * replace dictionary if match
1321  */
1322  if (cfgmap->mapdict == dictOld)
1323  {
1324  Datum repl_val[Natts_pg_ts_config_map];
1325  bool repl_null[Natts_pg_ts_config_map];
1326  bool repl_repl[Natts_pg_ts_config_map];
1327  HeapTuple newtup;
1328 
1329  memset(repl_val, 0, sizeof(repl_val));
1330  memset(repl_null, false, sizeof(repl_null));
1331  memset(repl_repl, false, sizeof(repl_repl));
1332 
1333  repl_val[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictNew);
1334  repl_repl[Anum_pg_ts_config_map_mapdict - 1] = true;
1335 
1336  newtup = heap_modify_tuple(maptup,
1337  RelationGetDescr(relMap),
1338  repl_val, repl_null, repl_repl);
1339  CatalogTupleUpdate(relMap, &newtup->t_self, newtup);
1340  }
1341  }
1342 
1343  systable_endscan(scan);
1344  }
1345  else
1346  {
1347  /*
1348  * Insertion of new entries
1349  */
1350  for (i = 0; i < ntoken; i++)
1351  {
1352  for (j = 0; j < ndict; j++)
1353  {
1354  Datum values[Natts_pg_ts_config_map];
1355  bool nulls[Natts_pg_ts_config_map];
1356 
1357  memset(nulls, false, sizeof(nulls));
1358  values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
1359  values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
1360  values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
1361  values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
1362 
1363  tup = heap_form_tuple(relMap->rd_att, values, nulls);
1364  CatalogTupleInsert(relMap, tup);
1365 
1366  heap_freetuple(tup);
1367  }
1368  }
1369  }
1370 
1371  EventTriggerCollectAlterTSConfig(stmt, cfgId, dictIds, ndict);
1372 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_ts_config * Form_pg_ts_config
Definition: pg_ts_config.h:48
#define RelationGetDescr(relation)
Definition: rel.h:482
FormData_pg_ts_config_map * Form_pg_ts_config_map
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2426
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
static int * getTokenTypes(Oid prsId, List *tokennames)
Definition: tsearchcmds.c:1159
char * c
void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId, Oid *dictIds, int ndicts)
uintptr_t Datum
Definition: postgres.h:367
TupleDesc rd_att
Definition: rel.h:110
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
static int list_length(const List *l)
Definition: pg_list.h:169
static Datum values[MAXATTR]
Definition: bootstrap.c:167
#define Int32GetDatum(X)
Definition: postgres.h:479
void * palloc(Size size)
Definition: mcxt.c:949
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:273
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
Definition: pg_list.h:50
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:221
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ makeDictionaryDependencies()

static ObjectAddress makeDictionaryDependencies ( HeapTuple  tuple)
static

Definition at line 302 of file tsearchcmds.c.

References ObjectAddress::classId, DEPENDENCY_NORMAL, GETSTRUCT, ObjectAddress::objectId, ObjectAddress::objectSubId, recordDependencyOn(), recordDependencyOnCurrentExtension(), and recordDependencyOnOwner().

Referenced by DefineTSDictionary().

303 {
304  Form_pg_ts_dict dict = (Form_pg_ts_dict) GETSTRUCT(tuple);
305  ObjectAddress myself,
306  referenced;
307 
308  myself.classId = TSDictionaryRelationId;
309  myself.objectId = dict->oid;
310  myself.objectSubId = 0;
311 
312  /* dependency on namespace */
313  referenced.classId = NamespaceRelationId;
314  referenced.objectId = dict->dictnamespace;
315  referenced.objectSubId = 0;
316  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
317 
318  /* dependency on owner */
319  recordDependencyOnOwner(myself.classId, myself.objectId, dict->dictowner);
320 
321  /* dependency on extension */
322  recordDependencyOnCurrentExtension(&myself, false);
323 
324  /* dependency on template */
325  referenced.classId = TSTemplateRelationId;
326  referenced.objectId = dict->dicttemplate;
327  referenced.objectSubId = 0;
328  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
329 
330  return myself;
331 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:164
FormData_pg_ts_dict * Form_pg_ts_dict
Definition: pg_ts_dict.h:52
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:138

◆ makeParserDependencies()

static ObjectAddress makeParserDependencies ( HeapTuple  tuple)
static

Definition at line 131 of file tsearchcmds.c.

References ObjectAddress::classId, DEPENDENCY_NORMAL, GETSTRUCT, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, recordDependencyOn(), and recordDependencyOnCurrentExtension().

Referenced by DefineTSParser().

132 {
134  ObjectAddress myself,
135  referenced;
136 
137  myself.classId = TSParserRelationId;
138  myself.objectId = prs->oid;
139  myself.objectSubId = 0;
140 
141  /* dependency on namespace */
142  referenced.classId = NamespaceRelationId;
143  referenced.objectId = prs->prsnamespace;
144  referenced.objectSubId = 0;
145  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
146 
147  /* dependency on extension */
148  recordDependencyOnCurrentExtension(&myself, false);
149 
150  /* dependencies on functions */
151  referenced.classId = ProcedureRelationId;
152  referenced.objectSubId = 0;
153 
154  referenced.objectId = prs->prsstart;
155  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
156 
157  referenced.objectId = prs->prstoken;
158  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
159 
160  referenced.objectId = prs->prsend;
161  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
162 
163  referenced.objectId = prs->prslextype;
164  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
165 
166  if (OidIsValid(prs->prsheadline))
167  {
168  referenced.objectId = prs->prsheadline;
169  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
170  }
171 
172  return myself;
173 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
#define OidIsValid(objectId)
Definition: c.h:651
FormData_pg_ts_parser * Form_pg_ts_parser
Definition: pg_ts_parser.h:55
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:138

◆ makeTSTemplateDependencies()

static ObjectAddress makeTSTemplateDependencies ( HeapTuple  tuple)
static

Definition at line 647 of file tsearchcmds.c.

References ObjectAddress::classId, DEPENDENCY_NORMAL, GETSTRUCT, ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, recordDependencyOn(), and recordDependencyOnCurrentExtension().

Referenced by DefineTSTemplate().

648 {
650  ObjectAddress myself,
651  referenced;
652 
653  myself.classId = TSTemplateRelationId;
654  myself.objectId = tmpl->oid;
655  myself.objectSubId = 0;
656 
657  /* dependency on namespace */
658  referenced.classId = NamespaceRelationId;
659  referenced.objectId = tmpl->tmplnamespace;
660  referenced.objectSubId = 0;
661  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
662 
663  /* dependency on extension */
664  recordDependencyOnCurrentExtension(&myself, false);
665 
666  /* dependencies on functions */
667  referenced.classId = ProcedureRelationId;
668  referenced.objectSubId = 0;
669 
670  referenced.objectId = tmpl->tmpllexize;
671  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
672 
673  if (OidIsValid(tmpl->tmplinit))
674  {
675  referenced.objectId = tmpl->tmplinit;
676  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
677  }
678 
679  return myself;
680 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
#define OidIsValid(objectId)
Definition: c.h:651
void recordDependencyOnCurrentExtension(const ObjectAddress *object, bool isReplace)
Definition: pg_depend.c:138
FormData_pg_ts_template * Form_pg_ts_template

◆ RemoveTSConfigurationById()

void RemoveTSConfigurationById ( Oid  cfgId)

Definition at line 1063 of file tsearchcmds.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), TSConfigMapIndexId, and TSCONFIGOID.

Referenced by doDeletion().

1064 {
1065  Relation relCfg,
1066  relMap;
1067  HeapTuple tup;
1068  ScanKeyData skey;
1069  SysScanDesc scan;
1070 
1071  /* Remove the pg_ts_config entry */
1072  relCfg = table_open(TSConfigRelationId, RowExclusiveLock);
1073 
1075 
1076  if (!HeapTupleIsValid(tup))
1077  elog(ERROR, "cache lookup failed for text search dictionary %u",
1078  cfgId);
1079 
1080  CatalogTupleDelete(relCfg, &tup->t_self);
1081 
1082  ReleaseSysCache(tup);
1083 
1084  table_close(relCfg, RowExclusiveLock);
1085 
1086  /* Remove any pg_ts_config_map entries */
1087  relMap = table_open(TSConfigMapRelationId, RowExclusiveLock);
1088 
1089  ScanKeyInit(&skey,
1090  Anum_pg_ts_config_map_mapcfg,
1091  BTEqualStrategyNumber, F_OIDEQ,
1092  ObjectIdGetDatum(cfgId));
1093 
1094  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1095  NULL, 1, &skey);
1096 
1097  while (HeapTupleIsValid((tup = systable_getnext(scan))))
1098  {
1099  CatalogTupleDelete(relMap, &tup->t_self);
1100  }
1101 
1102  systable_endscan(scan);
1103 
1104  table_close(relMap, RowExclusiveLock);
1105 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:214
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:273
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ serialize_deflist()

text* serialize_deflist ( List deflist)

Definition at line 1456 of file tsearchcmds.c.

References appendStringInfo(), appendStringInfoChar(), appendStringInfoString(), DefElem::arg, buf, cstring_to_text_with_len(), StringInfoData::data, defGetString(), DefElem::defname, ESCAPE_STRING_SYNTAX, initStringInfo(), IsA, StringInfoData::len, lfirst, lnext(), pfree(), quote_identifier(), SQL_STR_DOUBLE, and val.

Referenced by AlterTSDictionary(), and DefineTSDictionary().

1457 {
1458  text *result;
1460  ListCell *l;
1461 
1462  initStringInfo(&buf);
1463 
1464  foreach(l, deflist)
1465  {
1466  DefElem *defel = (DefElem *) lfirst(l);
1467  char *val = defGetString(defel);
1468 
1469  appendStringInfo(&buf, "%s = ",
1470  quote_identifier(defel->defname));
1471 
1472  /*
1473  * If the value is a T_Integer or T_Float, emit it without quotes,
1474  * otherwise with quotes. This is essential to allow correct
1475  * reconstruction of the node type as well as the value.
1476  */
1477  if (IsA(defel->arg, Integer) || IsA(defel->arg, Float))
1478  appendStringInfoString(&buf, val);
1479  else
1480  {
1481  /* If backslashes appear, force E syntax to quote them safely */
1482  if (strchr(val, '\\'))
1484  appendStringInfoChar(&buf, '\'');
1485  while (*val)
1486  {
1487  char ch = *val++;
1488 
1489  if (SQL_STR_DOUBLE(ch, true))
1490  appendStringInfoChar(&buf, ch);
1491  appendStringInfoChar(&buf, ch);
1492  }
1493  appendStringInfoChar(&buf, '\'');
1494  }
1495  if (lnext(deflist, l) != NULL)
1496  appendStringInfoString(&buf, ", ");
1497  }
1498 
1499  result = cstring_to_text_with_len(buf.data, buf.len);
1500  pfree(buf.data);
1501  return result;
1502 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10727
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
#define ESCAPE_STRING_SYNTAX
Definition: c.h:1137
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
char * defGetString(DefElem *def)
Definition: define.c:49
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:67
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:184
Node * arg
Definition: parsenodes.h:733
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define lfirst(lc)
Definition: pg_list.h:190
#define SQL_STR_DOUBLE(ch, escape_backslash)
Definition: c.h:1134
Definition: c.h:562
char * defname
Definition: parsenodes.h:732
long val
Definition: informix.c:664

◆ verify_dictoptions()

static void verify_dictoptions ( Oid  tmplId,
List dictoptions 
)
static

Definition at line 337 of file tsearchcmds.c.

References copyObject, elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, IsUnderPostmaster, NameStr, ObjectIdGetDatum, OidFunctionCall1, OidIsValid, PointerGetDatum, ReleaseSysCache(), SearchSysCache1(), and TSTEMPLATEOID.

Referenced by AlterTSDictionary(), and DefineTSDictionary().

338 {
339  HeapTuple tup;
340  Form_pg_ts_template tform;
341  Oid initmethod;
342 
343  /*
344  * Suppress this test when running in a standalone backend. This is a
345  * hack to allow initdb to create prefab dictionaries that might not
346  * actually be usable in template1's encoding (due to using external files
347  * that can't be translated into template1's encoding). We want to create
348  * them anyway, since they might be usable later in other databases.
349  */
350  if (!IsUnderPostmaster)
351  return;
352 
354  if (!HeapTupleIsValid(tup)) /* should not happen */
355  elog(ERROR, "cache lookup failed for text search template %u",
356  tmplId);
357  tform = (Form_pg_ts_template) GETSTRUCT(tup);
358 
359  initmethod = tform->tmplinit;
360 
361  if (!OidIsValid(initmethod))
362  {
363  /* If there is no init method, disallow any options */
364  if (dictoptions)
365  ereport(ERROR,
366  (errcode(ERRCODE_SYNTAX_ERROR),
367  errmsg("text search template \"%s\" does not accept options",
368  NameStr(tform->tmplname))));
369  }
370  else
371  {
372  /*
373  * Copy the options just in case init method thinks it can scribble on
374  * them ...
375  */
376  dictoptions = copyObject(dictoptions);
377 
378  /*
379  * Call the init method and see if it complains. We don't worry about
380  * it leaking memory, since our command will soon be over anyway.
381  */
382  (void) OidFunctionCall1(initmethod, PointerGetDatum(dictoptions));
383  }
384 
385  ReleaseSysCache(tup);
386 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:651
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:662
bool IsUnderPostmaster
Definition: globals.c:109
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:824
FormData_pg_ts_template * Form_pg_ts_template
#define elog(elevel,...)
Definition: elog.h:214
#define NameStr(name)
Definition: c.h:622
#define copyObject(obj)
Definition: nodes.h:645