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)
 
void RemoveTSParserById (Oid prsId)
 
static ObjectAddress makeDictionaryDependencies (HeapTuple tuple)
 
static void verify_dictoptions (Oid tmplId, List *dictoptions)
 
ObjectAddress DefineTSDictionary (List *names, List *parameters)
 
void RemoveTSDictionaryById (Oid dictId)
 
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)
 
void RemoveTSTemplateById (Oid tmplId)
 
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 1182 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().

1183 {
1184  HeapTuple tup;
1185  Oid cfgId;
1186  Relation relMap;
1187  ObjectAddress address;
1188 
1189  /* Find the configuration */
1190  tup = GetTSConfigTuple(stmt->cfgname);
1191  if (!HeapTupleIsValid(tup))
1192  ereport(ERROR,
1193  (errcode(ERRCODE_UNDEFINED_OBJECT),
1194  errmsg("text search configuration \"%s\" does not exist",
1195  NameListToString(stmt->cfgname))));
1196 
1197  cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid;
1198 
1199  /* must be owner */
1200  if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
1202  NameListToString(stmt->cfgname));
1203 
1204  relMap = table_open(TSConfigMapRelationId, RowExclusiveLock);
1205 
1206  /* Add or drop mappings */
1207  if (stmt->dicts)
1208  MakeConfigurationMapping(stmt, tup, relMap);
1209  else if (stmt->tokentype)
1210  DropConfigurationMapping(stmt, tup, relMap);
1211 
1212  /* Update dependencies */
1213  makeConfigurationDependencies(tup, true, relMap);
1214 
1215  InvokeObjectPostAlterHook(TSConfigRelationId, cfgId, 0);
1216 
1217  ObjectAddressSet(address, TSConfigRelationId, cfgId);
1218 
1219  table_close(relMap, RowExclusiveLock);
1220 
1221  ReleaseSysCache(tup);
1222 
1223  return address;
1224 }
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:448
bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
Definition: aclchk.c:5030
static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel)
Definition: tsearchcmds.c:879
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:1449
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3327
#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:854
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:1285

◆ AlterTSDictionary()

ObjectAddress AlterTSDictionary ( AlterTSDictionaryStmt stmt)

Definition at line 535 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().

536 {
537  HeapTuple tup,
538  newtup;
539  Relation rel;
540  Oid dictId;
541  ListCell *pl;
542  List *dictoptions;
543  Datum opt;
544  bool isnull;
545  Datum repl_val[Natts_pg_ts_dict];
546  bool repl_null[Natts_pg_ts_dict];
547  bool repl_repl[Natts_pg_ts_dict];
548  ObjectAddress address;
549 
550  dictId = get_ts_dict_oid(stmt->dictname, false);
551 
552  rel = table_open(TSDictionaryRelationId, RowExclusiveLock);
553 
555 
556  if (!HeapTupleIsValid(tup))
557  elog(ERROR, "cache lookup failed for text search dictionary %u",
558  dictId);
559 
560  /* must be owner */
561  if (!pg_ts_dict_ownercheck(dictId, GetUserId()))
563  NameListToString(stmt->dictname));
564 
565  /* deserialize the existing set of options */
566  opt = SysCacheGetAttr(TSDICTOID, tup,
567  Anum_pg_ts_dict_dictinitoption,
568  &isnull);
569  if (isnull)
570  dictoptions = NIL;
571  else
572  dictoptions = deserialize_deflist(opt);
573 
574  /*
575  * Modify the options list as per specified changes
576  */
577  foreach(pl, stmt->options)
578  {
579  DefElem *defel = (DefElem *) lfirst(pl);
580  ListCell *cell;
581 
582  /*
583  * Remove any matches ...
584  */
585  foreach(cell, dictoptions)
586  {
587  DefElem *oldel = (DefElem *) lfirst(cell);
588 
589  if (strcmp(oldel->defname, defel->defname) == 0)
590  dictoptions = foreach_delete_current(dictoptions, cell);
591  }
592 
593  /*
594  * and add new value if it's got one
595  */
596  if (defel->arg)
597  dictoptions = lappend(dictoptions, defel);
598  }
599 
600  /*
601  * Validate
602  */
603  verify_dictoptions(((Form_pg_ts_dict) GETSTRUCT(tup))->dicttemplate,
604  dictoptions);
605 
606  /*
607  * Looks good, update
608  */
609  memset(repl_val, 0, sizeof(repl_val));
610  memset(repl_null, false, sizeof(repl_null));
611  memset(repl_repl, false, sizeof(repl_repl));
612 
613  if (dictoptions)
614  repl_val[Anum_pg_ts_dict_dictinitoption - 1] =
615  PointerGetDatum(serialize_deflist(dictoptions));
616  else
617  repl_null[Anum_pg_ts_dict_dictinitoption - 1] = true;
618  repl_repl[Anum_pg_ts_dict_dictinitoption - 1] = true;
619 
620  newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
621  repl_val, repl_null, repl_repl);
622 
623  CatalogTupleUpdate(rel, &newtup->t_self, newtup);
624 
625  InvokeObjectPostAlterHook(TSDictionaryRelationId, dictId, 0);
626 
627  ObjectAddressSet(address, TSDictionaryRelationId, dictId);
628 
629  /*
630  * NOTE: because we only support altering the options, not the template,
631  * there is no need to update dependencies. This might have to change if
632  * the options ever reference inside-the-database objects.
633  */
634 
635  heap_freetuple(newtup);
636  ReleaseSysCache(tup);
637 
639 
640  return address;
641 }
#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:5003
#define RelationGetDescr(relation)
Definition: rel.h:482
Oid GetUserId(void)
Definition: miscinit.c:448
#define PointerGetDatum(X)
Definition: postgres.h:556
List * deserialize_deflist(Datum txt)
Definition: tsearchcmds.c:1583
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:3327
#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:1527
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:360
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#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 1796 of file tsearchcmds.c.

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

Referenced by deserialize_deflist().

1797 {
1798  /* If input was quoted, always emit as string */
1799  if (!was_quoted && val[0] != '\0')
1800  {
1801  int v;
1802  char *endptr;
1803 
1804  /* Try to parse as an integer */
1805  errno = 0;
1806  v = strtoint(val, &endptr, 10);
1807  if (errno == 0 && *endptr == '\0')
1808  return makeDefElem(pstrdup(name),
1809  (Node *) makeInteger(v),
1810  -1);
1811  /* Nope, how about as a float? */
1812  errno = 0;
1813  (void) strtod(val, &endptr);
1814  if (errno == 0 && *endptr == '\0')
1815  return makeDefElem(pstrdup(name),
1816  (Node *) makeFloat(pstrdup(val)),
1817  -1);
1818  }
1819  /* Just make it a string */
1820  return makeDefElem(pstrdup(name),
1821  (Node *) makeString(pstrdup(val)),
1822  -1);
1823 }
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:544
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:555
long val
Definition: informix.c:664

◆ DefineTSConfiguration()

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

Definition at line 966 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().

967 {
968  Relation cfgRel;
969  Relation mapRel = NULL;
970  HeapTuple tup;
971  Datum values[Natts_pg_ts_config];
972  bool nulls[Natts_pg_ts_config];
973  AclResult aclresult;
974  Oid namespaceoid;
975  char *cfgname;
976  NameData cname;
977  Oid sourceOid = InvalidOid;
978  Oid prsOid = InvalidOid;
979  Oid cfgOid;
980  ListCell *pl;
981  ObjectAddress address;
982 
983  /* Convert list of names to a name and namespace */
984  namespaceoid = QualifiedNameGetCreationNamespace(names, &cfgname);
985 
986  /* Check we have creation rights in target namespace */
987  aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
988  if (aclresult != ACLCHECK_OK)
989  aclcheck_error(aclresult, OBJECT_SCHEMA,
990  get_namespace_name(namespaceoid));
991 
992  /*
993  * loop over the definition list and extract the information we need.
994  */
995  foreach(pl, parameters)
996  {
997  DefElem *defel = (DefElem *) lfirst(pl);
998 
999  if (strcmp(defel->defname, "parser") == 0)
1000  prsOid = get_ts_parser_oid(defGetQualifiedName(defel), false);
1001  else if (strcmp(defel->defname, "copy") == 0)
1002  sourceOid = get_ts_config_oid(defGetQualifiedName(defel), false);
1003  else
1004  ereport(ERROR,
1005  (errcode(ERRCODE_SYNTAX_ERROR),
1006  errmsg("text search configuration parameter \"%s\" not recognized",
1007  defel->defname)));
1008  }
1009 
1010  if (OidIsValid(sourceOid) && OidIsValid(prsOid))
1011  ereport(ERROR,
1012  (errcode(ERRCODE_SYNTAX_ERROR),
1013  errmsg("cannot specify both PARSER and COPY options")));
1014 
1015  /* make copied tsconfig available to callers */
1016  if (copied && OidIsValid(sourceOid))
1017  {
1018  ObjectAddressSet(*copied,
1019  TSConfigRelationId,
1020  sourceOid);
1021  }
1022 
1023  /*
1024  * Look up source config if given.
1025  */
1026  if (OidIsValid(sourceOid))
1027  {
1028  Form_pg_ts_config cfg;
1029 
1030  tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(sourceOid));
1031  if (!HeapTupleIsValid(tup))
1032  elog(ERROR, "cache lookup failed for text search configuration %u",
1033  sourceOid);
1034 
1035  cfg = (Form_pg_ts_config) GETSTRUCT(tup);
1036 
1037  /* use source's parser */
1038  prsOid = cfg->cfgparser;
1039 
1040  ReleaseSysCache(tup);
1041  }
1042 
1043  /*
1044  * Validation
1045  */
1046  if (!OidIsValid(prsOid))
1047  ereport(ERROR,
1048  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1049  errmsg("text search parser is required")));
1050 
1051  cfgRel = table_open(TSConfigRelationId, RowExclusiveLock);
1052 
1053  /*
1054  * Looks good, build tuple and insert
1055  */
1056  memset(values, 0, sizeof(values));
1057  memset(nulls, false, sizeof(nulls));
1058 
1059  cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId,
1060  Anum_pg_ts_config_oid);
1061  values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
1062  namestrcpy(&cname, cfgname);
1063  values[Anum_pg_ts_config_cfgname - 1] = NameGetDatum(&cname);
1064  values[Anum_pg_ts_config_cfgnamespace - 1] = ObjectIdGetDatum(namespaceoid);
1065  values[Anum_pg_ts_config_cfgowner - 1] = ObjectIdGetDatum(GetUserId());
1066  values[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(prsOid);
1067 
1068  tup = heap_form_tuple(cfgRel->rd_att, values, nulls);
1069 
1070  CatalogTupleInsert(cfgRel, tup);
1071 
1072  if (OidIsValid(sourceOid))
1073  {
1074  /*
1075  * Copy token-dicts map from source config
1076  */
1077  ScanKeyData skey;
1078  SysScanDesc scan;
1079  HeapTuple maptup;
1080 
1081  mapRel = table_open(TSConfigMapRelationId, RowExclusiveLock);
1082 
1083  ScanKeyInit(&skey,
1084  Anum_pg_ts_config_map_mapcfg,
1085  BTEqualStrategyNumber, F_OIDEQ,
1086  ObjectIdGetDatum(sourceOid));
1087 
1088  scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
1089  NULL, 1, &skey);
1090 
1091  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1092  {
1094  HeapTuple newmaptup;
1095  Datum mapvalues[Natts_pg_ts_config_map];
1096  bool mapnulls[Natts_pg_ts_config_map];
1097 
1098  memset(mapvalues, 0, sizeof(mapvalues));
1099  memset(mapnulls, false, sizeof(mapnulls));
1100 
1101  mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
1102  mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
1103  mapvalues[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
1104  mapvalues[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
1105 
1106  newmaptup = heap_form_tuple(mapRel->rd_att, mapvalues, mapnulls);
1107 
1108  CatalogTupleInsert(mapRel, newmaptup);
1109 
1110  heap_freetuple(newmaptup);
1111  }
1112 
1113  systable_endscan(scan);
1114  }
1115 
1116  address = makeConfigurationDependencies(tup, false, mapRel);
1117 
1118  /* Post creation hook for new text search configuration */
1119  InvokeObjectPostCreateHook(TSConfigRelationId, cfgOid, 0);
1120 
1121  heap_freetuple(tup);
1122 
1123  if (mapRel)
1124  table_close(mapRel, RowExclusiveLock);
1125  table_close(cfgRel, RowExclusiveLock);
1126 
1127  return address;
1128 }
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:529
#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:448
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:879
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:644
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4658
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3327
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
Definition: c.h:609
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3191
#define RowExclusiveLock
Definition: lockdefs.h:38
#define TSConfigOidIndexId
Definition: indexing.h:265
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:268
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:183
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ DefineTSDictionary()

ObjectAddress DefineTSDictionary ( List names,
List parameters 
)

Definition at line 415 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().

416 {
417  ListCell *pl;
418  Relation dictRel;
419  HeapTuple tup;
420  Datum values[Natts_pg_ts_dict];
421  bool nulls[Natts_pg_ts_dict];
422  NameData dname;
423  Oid templId = InvalidOid;
424  List *dictoptions = NIL;
425  Oid dictOid;
426  Oid namespaceoid;
427  AclResult aclresult;
428  char *dictname;
429  ObjectAddress address;
430 
431  /* Convert list of names to a name and namespace */
432  namespaceoid = QualifiedNameGetCreationNamespace(names, &dictname);
433 
434  /* Check we have creation rights in target namespace */
435  aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
436  if (aclresult != ACLCHECK_OK)
437  aclcheck_error(aclresult, OBJECT_SCHEMA,
438  get_namespace_name(namespaceoid));
439 
440  /*
441  * loop over the definition list and extract the information we need.
442  */
443  foreach(pl, parameters)
444  {
445  DefElem *defel = (DefElem *) lfirst(pl);
446 
447  if (strcmp(defel->defname, "template") == 0)
448  {
449  templId = get_ts_template_oid(defGetQualifiedName(defel), false);
450  }
451  else
452  {
453  /* Assume it's an option for the dictionary itself */
454  dictoptions = lappend(dictoptions, defel);
455  }
456  }
457 
458  /*
459  * Validation
460  */
461  if (!OidIsValid(templId))
462  ereport(ERROR,
463  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
464  errmsg("text search template is required")));
465 
466  verify_dictoptions(templId, dictoptions);
467 
468 
469  dictRel = table_open(TSDictionaryRelationId, RowExclusiveLock);
470 
471  /*
472  * Looks good, insert
473  */
474  memset(values, 0, sizeof(values));
475  memset(nulls, false, sizeof(nulls));
476 
477  dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId,
478  Anum_pg_ts_dict_oid);
479  values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
480  namestrcpy(&dname, dictname);
481  values[Anum_pg_ts_dict_dictname - 1] = NameGetDatum(&dname);
482  values[Anum_pg_ts_dict_dictnamespace - 1] = ObjectIdGetDatum(namespaceoid);
483  values[Anum_pg_ts_dict_dictowner - 1] = ObjectIdGetDatum(GetUserId());
484  values[Anum_pg_ts_dict_dicttemplate - 1] = ObjectIdGetDatum(templId);
485  if (dictoptions)
486  values[Anum_pg_ts_dict_dictinitoption - 1] =
487  PointerGetDatum(serialize_deflist(dictoptions));
488  else
489  nulls[Anum_pg_ts_dict_dictinitoption - 1] = true;
490 
491  tup = heap_form_tuple(dictRel->rd_att, values, nulls);
492 
493  CatalogTupleInsert(dictRel, tup);
494 
495  address = makeDictionaryDependencies(tup);
496 
497  /* Post creation hook for new text search dictionary */
498  InvokeObjectPostCreateHook(TSDictionaryRelationId, dictOid, 0);
499 
500  heap_freetuple(tup);
501 
502  table_close(dictRel, RowExclusiveLock);
503 
504  return address;
505 }
#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:448
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:644
static ObjectAddress makeDictionaryDependencies(HeapTuple tuple)
Definition: tsearchcmds.c:325
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4658
#define TSDictionaryOidIndexId
Definition: indexing.h:273
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3327
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:84
Definition: c.h:609
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:1527
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:360
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:183

◆ 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:644
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Definition: c.h:609
#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:278
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:183

◆ DefineTSTemplate()

ObjectAddress DefineTSTemplate ( List names,
List parameters 
)

Definition at line 733 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().

734 {
735  ListCell *pl;
736  Relation tmplRel;
737  HeapTuple tup;
738  Datum values[Natts_pg_ts_template];
739  bool nulls[Natts_pg_ts_template];
740  NameData dname;
741  int i;
742  Oid tmplOid;
743  Oid namespaceoid;
744  char *tmplname;
745  ObjectAddress address;
746 
747  if (!superuser())
748  ereport(ERROR,
749  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
750  errmsg("must be superuser to create text search templates")));
751 
752  /* Convert list of names to a name and namespace */
753  namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname);
754 
755  tmplRel = table_open(TSTemplateRelationId, RowExclusiveLock);
756 
757  for (i = 0; i < Natts_pg_ts_template; i++)
758  {
759  nulls[i] = false;
760  values[i] = ObjectIdGetDatum(InvalidOid);
761  }
762 
763  tmplOid = GetNewOidWithIndex(tmplRel, TSTemplateOidIndexId,
764  Anum_pg_ts_dict_oid);
765  values[Anum_pg_ts_template_oid - 1] = ObjectIdGetDatum(tmplOid);
766  namestrcpy(&dname, tmplname);
767  values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname);
768  values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid);
769 
770  /*
771  * loop over the definition list and extract the information we need.
772  */
773  foreach(pl, parameters)
774  {
775  DefElem *defel = (DefElem *) lfirst(pl);
776 
777  if (strcmp(defel->defname, "init") == 0)
778  {
779  values[Anum_pg_ts_template_tmplinit - 1] =
780  get_ts_template_func(defel, Anum_pg_ts_template_tmplinit);
781  nulls[Anum_pg_ts_template_tmplinit - 1] = false;
782  }
783  else if (strcmp(defel->defname, "lexize") == 0)
784  {
785  values[Anum_pg_ts_template_tmpllexize - 1] =
786  get_ts_template_func(defel, Anum_pg_ts_template_tmpllexize);
787  nulls[Anum_pg_ts_template_tmpllexize - 1] = false;
788  }
789  else
790  ereport(ERROR,
791  (errcode(ERRCODE_SYNTAX_ERROR),
792  errmsg("text search template parameter \"%s\" not recognized",
793  defel->defname)));
794  }
795 
796  /*
797  * Validation
798  */
799  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_template_tmpllexize - 1])))
800  ereport(ERROR,
801  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
802  errmsg("text search template lexize method is required")));
803 
804  /*
805  * Looks good, insert
806  */
807  tup = heap_form_tuple(tmplRel->rd_att, values, nulls);
808 
809  CatalogTupleInsert(tmplRel, tup);
810 
811  address = makeTSTemplateDependencies(tup);
812 
813  /* Post creation hook for new text search template */
814  InvokeObjectPostCreateHook(TSTemplateRelationId, tmplOid, 0);
815 
816  heap_freetuple(tup);
817 
818  table_close(tmplRel, RowExclusiveLock);
819 
820  return address;
821 }
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:651
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:644
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Definition: c.h:609
#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:694
#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:283
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:183

◆ deserialize_deflist()

List* deserialize_deflist ( Datum  txt)

Definition at line 1583 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().

1584 {
1585  text *in = DatumGetTextPP(txt); /* in case it's toasted */
1586  List *result = NIL;
1587  int len = VARSIZE_ANY_EXHDR(in);
1588  char *ptr,
1589  *endptr,
1590  *workspace,
1591  *wsptr = NULL,
1592  *startvalue = NULL;
1593  typedef enum
1594  {
1595  CS_WAITKEY,
1596  CS_INKEY,
1597  CS_INQKEY,
1598  CS_WAITEQ,
1599  CS_WAITVALUE,
1600  CS_INSQVALUE,
1601  CS_INDQVALUE,
1602  CS_INWVALUE
1603  } ds_state;
1604  ds_state state = CS_WAITKEY;
1605 
1606  workspace = (char *) palloc(len + 1); /* certainly enough room */
1607  ptr = VARDATA_ANY(in);
1608  endptr = ptr + len;
1609  for (; ptr < endptr; ptr++)
1610  {
1611  switch (state)
1612  {
1613  case CS_WAITKEY:
1614  if (isspace((unsigned char) *ptr) || *ptr == ',')
1615  continue;
1616  if (*ptr == '"')
1617  {
1618  wsptr = workspace;
1619  state = CS_INQKEY;
1620  }
1621  else
1622  {
1623  wsptr = workspace;
1624  *wsptr++ = *ptr;
1625  state = CS_INKEY;
1626  }
1627  break;
1628  case CS_INKEY:
1629  if (isspace((unsigned char) *ptr))
1630  {
1631  *wsptr++ = '\0';
1632  state = CS_WAITEQ;
1633  }
1634  else if (*ptr == '=')
1635  {
1636  *wsptr++ = '\0';
1637  state = CS_WAITVALUE;
1638  }
1639  else
1640  {
1641  *wsptr++ = *ptr;
1642  }
1643  break;
1644  case CS_INQKEY:
1645  if (*ptr == '"')
1646  {
1647  if (ptr + 1 < endptr && ptr[1] == '"')
1648  {
1649  /* copy only one of the two quotes */
1650  *wsptr++ = *ptr++;
1651  }
1652  else
1653  {
1654  *wsptr++ = '\0';
1655  state = CS_WAITEQ;
1656  }
1657  }
1658  else
1659  {
1660  *wsptr++ = *ptr;
1661  }
1662  break;
1663  case CS_WAITEQ:
1664  if (*ptr == '=')
1665  state = CS_WAITVALUE;
1666  else if (!isspace((unsigned char) *ptr))
1667  ereport(ERROR,
1668  (errcode(ERRCODE_SYNTAX_ERROR),
1669  errmsg("invalid parameter list format: \"%s\"",
1670  text_to_cstring(in))));
1671  break;
1672  case CS_WAITVALUE:
1673  if (*ptr == '\'')
1674  {
1675  startvalue = wsptr;
1676  state = CS_INSQVALUE;
1677  }
1678  else if (*ptr == 'E' && ptr + 1 < endptr && ptr[1] == '\'')
1679  {
1680  ptr++;
1681  startvalue = wsptr;
1682  state = CS_INSQVALUE;
1683  }
1684  else if (*ptr == '"')
1685  {
1686  startvalue = wsptr;
1687  state = CS_INDQVALUE;
1688  }
1689  else if (!isspace((unsigned char) *ptr))
1690  {
1691  startvalue = wsptr;
1692  *wsptr++ = *ptr;
1693  state = CS_INWVALUE;
1694  }
1695  break;
1696  case CS_INSQVALUE:
1697  if (*ptr == '\'')
1698  {
1699  if (ptr + 1 < endptr && ptr[1] == '\'')
1700  {
1701  /* copy only one of the two quotes */
1702  *wsptr++ = *ptr++;
1703  }
1704  else
1705  {
1706  *wsptr++ = '\0';
1707  result = lappend(result,
1708  buildDefItem(workspace,
1709  startvalue,
1710  true));
1711  state = CS_WAITKEY;
1712  }
1713  }
1714  else if (*ptr == '\\')
1715  {
1716  if (ptr + 1 < endptr && ptr[1] == '\\')
1717  {
1718  /* copy only one of the two backslashes */
1719  *wsptr++ = *ptr++;
1720  }
1721  else
1722  *wsptr++ = *ptr;
1723  }
1724  else
1725  {
1726  *wsptr++ = *ptr;
1727  }
1728  break;
1729  case CS_INDQVALUE:
1730  if (*ptr == '"')
1731  {
1732  if (ptr + 1 < endptr && ptr[1] == '"')
1733  {
1734  /* copy only one of the two quotes */
1735  *wsptr++ = *ptr++;
1736  }
1737  else
1738  {
1739  *wsptr++ = '\0';
1740  result = lappend(result,
1741  buildDefItem(workspace,
1742  startvalue,
1743  true));
1744  state = CS_WAITKEY;
1745  }
1746  }
1747  else
1748  {
1749  *wsptr++ = *ptr;
1750  }
1751  break;
1752  case CS_INWVALUE:
1753  if (*ptr == ',' || isspace((unsigned char) *ptr))
1754  {
1755  *wsptr++ = '\0';
1756  result = lappend(result,
1757  buildDefItem(workspace,
1758  startvalue,
1759  false));
1760  state = CS_WAITKEY;
1761  }
1762  else
1763  {
1764  *wsptr++ = *ptr;
1765  }
1766  break;
1767  default:
1768  elog(ERROR, "unrecognized deserialize_deflist state: %d",
1769  state);
1770  }
1771  }
1772 
1773  if (state == CS_INWVALUE)
1774  {
1775  *wsptr++ = '\0';
1776  result = lappend(result,
1777  buildDefItem(workspace,
1778  startvalue,
1779  false));
1780  }
1781  else if (state != CS_WAITKEY)
1782  ereport(ERROR,
1783  (errcode(ERRCODE_SYNTAX_ERROR),
1784  errmsg("invalid parameter list format: \"%s\"",
1785  text_to_cstring(in))));
1786 
1787  pfree(workspace);
1788 
1789  return result;
1790 }
#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:1796
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:555
Definition: pg_list.h:50

◆ DropConfigurationMapping()

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

Definition at line 1449 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().

1451 {
1452  Form_pg_ts_config tsform;
1453  Oid cfgId;
1454  ScanKeyData skey[2];
1455  SysScanDesc scan;
1456  HeapTuple maptup;
1457  int i;
1458  Oid prsId;
1459  int *tokens;
1460  ListCell *c;
1461 
1462  tsform = (Form_pg_ts_config) GETSTRUCT(tup);
1463  cfgId = tsform->oid;
1464  prsId = tsform->cfgparser;
1465 
1466  tokens = getTokenTypes(prsId, stmt->tokentype);
1467 
1468  i = 0;
1469  foreach(c, stmt->tokentype)
1470  {
1471  Value *val = (Value *) lfirst(c);
1472  bool found = false;
1473 
1474  ScanKeyInit(&skey[0],
1475  Anum_pg_ts_config_map_mapcfg,
1476  BTEqualStrategyNumber, F_OIDEQ,
1477  ObjectIdGetDatum(cfgId));
1478  ScanKeyInit(&skey[1],
1479  Anum_pg_ts_config_map_maptokentype,
1480  BTEqualStrategyNumber, F_INT4EQ,
1481  Int32GetDatum(tokens[i]));
1482 
1483  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1484  NULL, 2, skey);
1485 
1486  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1487  {
1488  CatalogTupleDelete(relMap, &maptup->t_self);
1489  found = true;
1490  }
1491 
1492  systable_endscan(scan);
1493 
1494  if (!found)
1495  {
1496  if (!stmt->missing_ok)
1497  {
1498  ereport(ERROR,
1499  (errcode(ERRCODE_UNDEFINED_OBJECT),
1500  errmsg("mapping for token type \"%s\" does not exist",
1501  strVal(val))));
1502  }
1503  else
1504  {
1505  ereport(NOTICE,
1506  (errmsg("mapping for token type \"%s\" does not exist, skipping",
1507  strVal(val))));
1508  }
1509  }
1510 
1511  i++;
1512  }
1513 
1514  EventTriggerCollectAlterTSConfig(stmt, cfgId, NULL, 0);
1515 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#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:269
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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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:1230
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:268
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:327
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 651 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().

652 {
653  List *funcName = defGetQualifiedName(defel);
654  Oid typeId[4];
655  Oid retTypeId;
656  int nargs;
657  Oid procOid;
658 
659  retTypeId = INTERNALOID;
660  typeId[0] = INTERNALOID;
661  typeId[1] = INTERNALOID;
662  typeId[2] = INTERNALOID;
663  typeId[3] = INTERNALOID;
664  switch (attnum)
665  {
666  case Anum_pg_ts_template_tmplinit:
667  nargs = 1;
668  break;
669  case Anum_pg_ts_template_tmpllexize:
670  nargs = 4;
671  break;
672  default:
673  /* should not be here */
674  elog(ERROR, "unrecognized attribute for text search template: %d",
675  attnum);
676  nargs = 0; /* keep compiler quiet */
677  }
678 
679  procOid = LookupFuncName(funcName, nargs, typeId, false);
680  if (get_func_rettype(procOid) != retTypeId)
681  ereport(ERROR,
682  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
683  errmsg("function %s should return type %s",
684  func_signature_string(funcName, nargs, NIL, typeId),
685  format_type_be(retTypeId))));
686 
687  return ObjectIdGetDatum(procOid);
688 }
#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:327
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 1230 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().

1231 {
1233  LexDescr *list;
1234  int *res,
1235  i,
1236  ntoken;
1237  ListCell *tn;
1238 
1239  ntoken = list_length(tokennames);
1240  if (ntoken == 0)
1241  return NULL;
1242  res = (int *) palloc(sizeof(int) * ntoken);
1243 
1244  if (!OidIsValid(prs->lextypeOid))
1245  elog(ERROR, "method lextype isn't defined for text search parser %u",
1246  prsId);
1247 
1248  /* lextype takes one dummy argument */
1250  (Datum) 0));
1251 
1252  i = 0;
1253  foreach(tn, tokennames)
1254  {
1255  Value *val = (Value *) lfirst(tn);
1256  bool found = false;
1257  int j;
1258 
1259  j = 0;
1260  while (list && list[j].lexid)
1261  {
1262  if (strcmp(strVal(val), list[j].alias) == 0)
1263  {
1264  res[i] = list[j].lexid;
1265  found = true;
1266  break;
1267  }
1268  j++;
1269  }
1270  if (!found)
1271  ereport(ERROR,
1272  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1273  errmsg("token type \"%s\" does not exist",
1274  strVal(val))));
1275  i++;
1276  }
1277 
1278  return res;
1279 }
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:644
#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 854 of file tsearchcmds.c.

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

Referenced by AlterTSConfiguration().

855 {
856  HeapTuple tup;
857  Oid cfgId;
858 
859  cfgId = get_ts_config_oid(names, true);
860  if (!OidIsValid(cfgId))
861  return NULL;
862 
864 
865  if (!HeapTupleIsValid(tup)) /* should not happen */
866  elog(ERROR, "cache lookup failed for text search configuration %u",
867  cfgId);
868 
869  return tup;
870 }
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:644
#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 879 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().

881 {
883  ObjectAddresses *addrs;
884  ObjectAddress myself,
885  referenced;
886 
887  myself.classId = TSConfigRelationId;
888  myself.objectId = cfg->oid;
889  myself.objectSubId = 0;
890 
891  /* for ALTER case, first flush old dependencies, except extension deps */
892  if (removeOld)
893  {
894  deleteDependencyRecordsFor(myself.classId, myself.objectId, true);
896  }
897 
898  /*
899  * We use an ObjectAddresses list to remove possible duplicate
900  * dependencies from the config map info. The pg_ts_config items
901  * shouldn't be duplicates, but might as well fold them all into one call.
902  */
903  addrs = new_object_addresses();
904 
905  /* dependency on namespace */
906  referenced.classId = NamespaceRelationId;
907  referenced.objectId = cfg->cfgnamespace;
908  referenced.objectSubId = 0;
909  add_exact_object_address(&referenced, addrs);
910 
911  /* dependency on owner */
912  recordDependencyOnOwner(myself.classId, myself.objectId, cfg->cfgowner);
913 
914  /* dependency on extension */
915  recordDependencyOnCurrentExtension(&myself, removeOld);
916 
917  /* dependency on parser */
918  referenced.classId = TSParserRelationId;
919  referenced.objectId = cfg->cfgparser;
920  referenced.objectSubId = 0;
921  add_exact_object_address(&referenced, addrs);
922 
923  /* dependencies on dictionaries listed in config map */
924  if (mapRel)
925  {
926  ScanKeyData skey;
927  SysScanDesc scan;
928  HeapTuple maptup;
929 
930  /* CCI to ensure we can see effects of caller's changes */
932 
933  ScanKeyInit(&skey,
934  Anum_pg_ts_config_map_mapcfg,
935  BTEqualStrategyNumber, F_OIDEQ,
936  ObjectIdGetDatum(myself.objectId));
937 
938  scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
939  NULL, 1, &skey);
940 
941  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
942  {
944 
945  referenced.classId = TSDictionaryRelationId;
946  referenced.objectId = cfgmap->mapdict;
947  referenced.objectSubId = 0;
948  add_exact_object_address(&referenced, addrs);
949  }
950 
951  systable_endscan(scan);
952  }
953 
954  /* Record 'em (this includes duplicate elimination) */
956 
957  free_object_addresses(addrs);
958 
959  return myself;
960 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#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:2682
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:2473
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
Definition: pg_shdepend.c:164
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2418
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2713
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
Definition: pg_shdepend.c:907
void CommandCounterIncrement(void)
Definition: xact.c:1006
#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:268
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ MakeConfigurationMapping()

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

Definition at line 1285 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().

1287 {
1288  Form_pg_ts_config tsform;
1289  Oid cfgId;
1290  ScanKeyData skey[2];
1291  SysScanDesc scan;
1292  HeapTuple maptup;
1293  int i;
1294  int j;
1295  Oid prsId;
1296  int *tokens,
1297  ntoken;
1298  Oid *dictIds;
1299  int ndict;
1300  ListCell *c;
1301 
1302  tsform = (Form_pg_ts_config) GETSTRUCT(tup);
1303  cfgId = tsform->oid;
1304  prsId = tsform->cfgparser;
1305 
1306  tokens = getTokenTypes(prsId, stmt->tokentype);
1307  ntoken = list_length(stmt->tokentype);
1308 
1309  if (stmt->override)
1310  {
1311  /*
1312  * delete maps for tokens if they exist and command was ALTER
1313  */
1314  for (i = 0; i < ntoken; i++)
1315  {
1316  ScanKeyInit(&skey[0],
1317  Anum_pg_ts_config_map_mapcfg,
1318  BTEqualStrategyNumber, F_OIDEQ,
1319  ObjectIdGetDatum(cfgId));
1320  ScanKeyInit(&skey[1],
1321  Anum_pg_ts_config_map_maptokentype,
1322  BTEqualStrategyNumber, F_INT4EQ,
1323  Int32GetDatum(tokens[i]));
1324 
1325  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1326  NULL, 2, skey);
1327 
1328  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1329  {
1330  CatalogTupleDelete(relMap, &maptup->t_self);
1331  }
1332 
1333  systable_endscan(scan);
1334  }
1335  }
1336 
1337  /*
1338  * Convert list of dictionary names to array of dict OIDs
1339  */
1340  ndict = list_length(stmt->dicts);
1341  dictIds = (Oid *) palloc(sizeof(Oid) * ndict);
1342  i = 0;
1343  foreach(c, stmt->dicts)
1344  {
1345  List *names = (List *) lfirst(c);
1346 
1347  dictIds[i] = get_ts_dict_oid(names, false);
1348  i++;
1349  }
1350 
1351  if (stmt->replace)
1352  {
1353  /*
1354  * Replace a specific dictionary in existing entries
1355  */
1356  Oid dictOld = dictIds[0],
1357  dictNew = dictIds[1];
1358 
1359  ScanKeyInit(&skey[0],
1360  Anum_pg_ts_config_map_mapcfg,
1361  BTEqualStrategyNumber, F_OIDEQ,
1362  ObjectIdGetDatum(cfgId));
1363 
1364  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1365  NULL, 1, skey);
1366 
1367  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1368  {
1370 
1371  /*
1372  * check if it's one of target token types
1373  */
1374  if (tokens)
1375  {
1376  bool tokmatch = false;
1377 
1378  for (j = 0; j < ntoken; j++)
1379  {
1380  if (cfgmap->maptokentype == tokens[j])
1381  {
1382  tokmatch = true;
1383  break;
1384  }
1385  }
1386  if (!tokmatch)
1387  continue;
1388  }
1389 
1390  /*
1391  * replace dictionary if match
1392  */
1393  if (cfgmap->mapdict == dictOld)
1394  {
1395  Datum repl_val[Natts_pg_ts_config_map];
1396  bool repl_null[Natts_pg_ts_config_map];
1397  bool repl_repl[Natts_pg_ts_config_map];
1398  HeapTuple newtup;
1399 
1400  memset(repl_val, 0, sizeof(repl_val));
1401  memset(repl_null, false, sizeof(repl_null));
1402  memset(repl_repl, false, sizeof(repl_repl));
1403 
1404  repl_val[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictNew);
1405  repl_repl[Anum_pg_ts_config_map_mapdict - 1] = true;
1406 
1407  newtup = heap_modify_tuple(maptup,
1408  RelationGetDescr(relMap),
1409  repl_val, repl_null, repl_repl);
1410  CatalogTupleUpdate(relMap, &newtup->t_self, newtup);
1411  }
1412  }
1413 
1414  systable_endscan(scan);
1415  }
1416  else
1417  {
1418  /*
1419  * Insertion of new entries
1420  */
1421  for (i = 0; i < ntoken; i++)
1422  {
1423  for (j = 0; j < ndict; j++)
1424  {
1425  Datum values[Natts_pg_ts_config_map];
1426  bool nulls[Natts_pg_ts_config_map];
1427 
1428  memset(nulls, false, sizeof(nulls));
1429  values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
1430  values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
1431  values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
1432  values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
1433 
1434  tup = heap_form_tuple(relMap->rd_att, values, nulls);
1435  CatalogTupleInsert(relMap, tup);
1436 
1437  heap_freetuple(tup);
1438  }
1439  }
1440  }
1441 
1442  EventTriggerCollectAlterTSConfig(stmt, cfgId, dictIds, ndict);
1443 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#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:269
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:356
Oid get_ts_dict_oid(List *names, bool missing_ok)
Definition: namespace.c:2426
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
static int * getTokenTypes(Oid prsId, List *tokennames)
Definition: tsearchcmds.c:1230
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:224
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:268
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:183
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ makeDictionaryDependencies()

static ObjectAddress makeDictionaryDependencies ( HeapTuple  tuple)
static

Definition at line 325 of file tsearchcmds.c.

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

Referenced by DefineTSDictionary().

326 {
327  Form_pg_ts_dict dict = (Form_pg_ts_dict) GETSTRUCT(tuple);
328  ObjectAddress myself,
329  referenced;
330 
331  myself.classId = TSDictionaryRelationId;
332  myself.objectId = dict->oid;
333  myself.objectSubId = 0;
334 
335  /* dependency on namespace */
336  referenced.classId = NamespaceRelationId;
337  referenced.objectId = dict->dictnamespace;
338  referenced.objectSubId = 0;
339  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
340 
341  /* dependency on owner */
342  recordDependencyOnOwner(myself.classId, myself.objectId, dict->dictowner);
343 
344  /* dependency on extension */
345  recordDependencyOnCurrentExtension(&myself, false);
346 
347  /* dependency on template */
348  referenced.classId = TSTemplateRelationId;
349  referenced.objectId = dict->dicttemplate;
350  referenced.objectSubId = 0;
351  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
352 
353  return myself;
354 }
#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:644
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 694 of file tsearchcmds.c.

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

Referenced by DefineTSTemplate().

695 {
697  ObjectAddress myself,
698  referenced;
699 
700  myself.classId = TSTemplateRelationId;
701  myself.objectId = tmpl->oid;
702  myself.objectSubId = 0;
703 
704  /* dependency on namespace */
705  referenced.classId = NamespaceRelationId;
706  referenced.objectId = tmpl->tmplnamespace;
707  referenced.objectSubId = 0;
708  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
709 
710  /* dependency on extension */
711  recordDependencyOnCurrentExtension(&myself, false);
712 
713  /* dependencies on functions */
714  referenced.classId = ProcedureRelationId;
715  referenced.objectSubId = 0;
716 
717  referenced.objectId = tmpl->tmpllexize;
718  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
719 
720  if (OidIsValid(tmpl->tmplinit))
721  {
722  referenced.objectId = tmpl->tmplinit;
723  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
724  }
725 
726  return myself;
727 }
#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:644
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 1134 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().

1135 {
1136  Relation relCfg,
1137  relMap;
1138  HeapTuple tup;
1139  ScanKeyData skey;
1140  SysScanDesc scan;
1141 
1142  /* Remove the pg_ts_config entry */
1143  relCfg = table_open(TSConfigRelationId, RowExclusiveLock);
1144 
1146 
1147  if (!HeapTupleIsValid(tup))
1148  elog(ERROR, "cache lookup failed for text search dictionary %u",
1149  cfgId);
1150 
1151  CatalogTupleDelete(relCfg, &tup->t_self);
1152 
1153  ReleaseSysCache(tup);
1154 
1155  table_close(relCfg, RowExclusiveLock);
1156 
1157  /* Remove any pg_ts_config_map entries */
1158  relMap = table_open(TSConfigMapRelationId, RowExclusiveLock);
1159 
1160  ScanKeyInit(&skey,
1161  Anum_pg_ts_config_map_mapcfg,
1162  BTEqualStrategyNumber, F_OIDEQ,
1163  ObjectIdGetDatum(cfgId));
1164 
1165  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1166  NULL, 1, &skey);
1167 
1168  while (HeapTupleIsValid((tup = systable_getnext(scan))))
1169  {
1170  CatalogTupleDelete(relMap, &tup->t_self);
1171  }
1172 
1173  systable_endscan(scan);
1174 
1175  table_close(relMap, RowExclusiveLock);
1176 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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:268
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ RemoveTSDictionaryById()

void RemoveTSDictionaryById ( Oid  dictId)

Definition at line 511 of file tsearchcmds.c.

References CatalogTupleDelete(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), table_open(), and TSDICTOID.

Referenced by doDeletion().

512 {
513  Relation relation;
514  HeapTuple tup;
515 
516  relation = table_open(TSDictionaryRelationId, RowExclusiveLock);
517 
519 
520  if (!HeapTupleIsValid(tup))
521  elog(ERROR, "cache lookup failed for text search dictionary %u",
522  dictId);
523 
524  CatalogTupleDelete(relation, &tup->t_self);
525 
526  ReleaseSysCache(tup);
527 
528  table_close(relation, RowExclusiveLock);
529 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
#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
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ RemoveTSParserById()

void RemoveTSParserById ( Oid  prsId)

Definition at line 298 of file tsearchcmds.c.

References CatalogTupleDelete(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), table_open(), and TSPARSEROID.

Referenced by doDeletion().

299 {
300  Relation relation;
301  HeapTuple tup;
302 
303  relation = table_open(TSParserRelationId, RowExclusiveLock);
304 
306 
307  if (!HeapTupleIsValid(tup))
308  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
309 
310  CatalogTupleDelete(relation, &tup->t_self);
311 
312  ReleaseSysCache(tup);
313 
314  table_close(relation, RowExclusiveLock);
315 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
#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
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ RemoveTSTemplateById()

void RemoveTSTemplateById ( Oid  tmplId)

Definition at line 827 of file tsearchcmds.c.

References CatalogTupleDelete(), elog, ERROR, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), table_open(), and TSTEMPLATEOID.

Referenced by doDeletion().

828 {
829  Relation relation;
830  HeapTuple tup;
831 
832  relation = table_open(TSTemplateRelationId, RowExclusiveLock);
833 
835 
836  if (!HeapTupleIsValid(tup))
837  elog(ERROR, "cache lookup failed for text search template %u",
838  tmplId);
839 
840  CatalogTupleDelete(relation, &tup->t_self);
841 
842  ReleaseSysCache(tup);
843 
844  table_close(relation, RowExclusiveLock);
845 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
#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
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ serialize_deflist()

text* serialize_deflist ( List deflist)

Definition at line 1527 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().

1528 {
1529  text *result;
1531  ListCell *l;
1532 
1533  initStringInfo(&buf);
1534 
1535  foreach(l, deflist)
1536  {
1537  DefElem *defel = (DefElem *) lfirst(l);
1538  char *val = defGetString(defel);
1539 
1540  appendStringInfo(&buf, "%s = ",
1541  quote_identifier(defel->defname));
1542 
1543  /*
1544  * If the value is a T_Integer or T_Float, emit it without quotes,
1545  * otherwise with quotes. This is essential to allow correct
1546  * reconstruction of the node type as well as the value.
1547  */
1548  if (IsA(defel->arg, Integer) || IsA(defel->arg, Float))
1549  appendStringInfoString(&buf, val);
1550  else
1551  {
1552  /* If backslashes appear, force E syntax to quote them safely */
1553  if (strchr(val, '\\'))
1555  appendStringInfoChar(&buf, '\'');
1556  while (*val)
1557  {
1558  char ch = *val++;
1559 
1560  if (SQL_STR_DOUBLE(ch, true))
1561  appendStringInfoChar(&buf, ch);
1562  appendStringInfoChar(&buf, ch);
1563  }
1564  appendStringInfoChar(&buf, '\'');
1565  }
1566  if (lnext(deflist, l) != NULL)
1567  appendStringInfoString(&buf, ", ");
1568  }
1569 
1570  result = cstring_to_text_with_len(buf.data, buf.len);
1571  pfree(buf.data);
1572  return result;
1573 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10737
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
#define ESCAPE_STRING_SYNTAX
Definition: c.h:1130
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:1127
Definition: c.h:555
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 360 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().

361 {
362  HeapTuple tup;
363  Form_pg_ts_template tform;
364  Oid initmethod;
365 
366  /*
367  * Suppress this test when running in a standalone backend. This is a
368  * hack to allow initdb to create prefab dictionaries that might not
369  * actually be usable in template1's encoding (due to using external files
370  * that can't be translated into template1's encoding). We want to create
371  * them anyway, since they might be usable later in other databases.
372  */
373  if (!IsUnderPostmaster)
374  return;
375 
377  if (!HeapTupleIsValid(tup)) /* should not happen */
378  elog(ERROR, "cache lookup failed for text search template %u",
379  tmplId);
380  tform = (Form_pg_ts_template) GETSTRUCT(tup);
381 
382  initmethod = tform->tmplinit;
383 
384  if (!OidIsValid(initmethod))
385  {
386  /* If there is no init method, disallow any options */
387  if (dictoptions)
388  ereport(ERROR,
389  (errcode(ERRCODE_SYNTAX_ERROR),
390  errmsg("text search template \"%s\" does not accept options",
391  NameStr(tform->tmplname))));
392  }
393  else
394  {
395  /*
396  * Copy the options just in case init method thinks it can scribble on
397  * them ...
398  */
399  dictoptions = copyObject(dictoptions);
400 
401  /*
402  * Call the init method and see if it complains. We don't worry about
403  * it leaking memory, since our command will soon be over anyway.
404  */
405  (void) OidFunctionCall1(initmethod, PointerGetDatum(dictoptions));
406  }
407 
408  ReleaseSysCache(tup);
409 }
#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:644
#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:615
#define copyObject(obj)
Definition: nodes.h:645