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 "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 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 1179 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().

1180 {
1181  HeapTuple tup;
1182  Oid cfgId;
1183  Relation relMap;
1184  ObjectAddress address;
1185 
1186  /* Find the configuration */
1187  tup = GetTSConfigTuple(stmt->cfgname);
1188  if (!HeapTupleIsValid(tup))
1189  ereport(ERROR,
1190  (errcode(ERRCODE_UNDEFINED_OBJECT),
1191  errmsg("text search configuration \"%s\" does not exist",
1192  NameListToString(stmt->cfgname))));
1193 
1194  cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid;
1195 
1196  /* must be owner */
1197  if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
1199  NameListToString(stmt->cfgname));
1200 
1201  relMap = table_open(TSConfigMapRelationId, RowExclusiveLock);
1202 
1203  /* Add or drop mappings */
1204  if (stmt->dicts)
1205  MakeConfigurationMapping(stmt, tup, relMap);
1206  else if (stmt->tokentype)
1207  DropConfigurationMapping(stmt, tup, relMap);
1208 
1209  /* Update dependencies */
1210  makeConfigurationDependencies(tup, true, relMap);
1211 
1212  InvokeObjectPostAlterHook(TSConfigRelationId, cfgId, 0);
1213 
1214  ObjectAddressSet(address, TSConfigRelationId, cfgId);
1215 
1216  table_close(relMap, RowExclusiveLock);
1217 
1218  ReleaseSysCache(tup);
1219 
1220  return address;
1221 }
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:380
bool pg_ts_config_ownercheck(Oid cfg_oid, Oid roleid)
Definition: aclchk.c:5065
static ObjectAddress makeConfigurationDependencies(HeapTuple tuple, bool removeOld, Relation mapRel)
Definition: tsearchcmds.c:876
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
Definition: tsearchcmds.c:1446
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition: aclchk.c:3353
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
static HeapTuple GetTSConfigTuple(List *names)
Definition: tsearchcmds.c:851
char * NameListToString(List *names)
Definition: namespace.c:3094
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#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:784
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap)
Definition: tsearchcmds.c:1282

◆ AlterTSDictionary()

ObjectAddress AlterTSDictionary ( AlterTSDictionaryStmt stmt)

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

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

◆ DefineTSConfiguration()

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

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

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

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

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

731 {
732  ListCell *pl;
733  Relation tmplRel;
734  HeapTuple tup;
735  Datum values[Natts_pg_ts_template];
736  bool nulls[Natts_pg_ts_template];
737  NameData dname;
738  int i;
739  Oid tmplOid;
740  Oid namespaceoid;
741  char *tmplname;
742  ObjectAddress address;
743 
744  if (!superuser())
745  ereport(ERROR,
746  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
747  errmsg("must be superuser to create text search templates")));
748 
749  /* Convert list of names to a name and namespace */
750  namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname);
751 
752  tmplRel = table_open(TSTemplateRelationId, RowExclusiveLock);
753 
754  for (i = 0; i < Natts_pg_ts_template; i++)
755  {
756  nulls[i] = false;
757  values[i] = ObjectIdGetDatum(InvalidOid);
758  }
759 
760  tmplOid = GetNewOidWithIndex(tmplRel, TSTemplateOidIndexId,
761  Anum_pg_ts_dict_oid);
762  values[Anum_pg_ts_template_oid - 1] = ObjectIdGetDatum(tmplOid);
763  namestrcpy(&dname, tmplname);
764  values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname);
765  values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid);
766 
767  /*
768  * loop over the definition list and extract the information we need.
769  */
770  foreach(pl, parameters)
771  {
772  DefElem *defel = (DefElem *) lfirst(pl);
773 
774  if (strcmp(defel->defname, "init") == 0)
775  {
776  values[Anum_pg_ts_template_tmplinit - 1] =
777  get_ts_template_func(defel, Anum_pg_ts_template_tmplinit);
778  nulls[Anum_pg_ts_template_tmplinit - 1] = false;
779  }
780  else if (strcmp(defel->defname, "lexize") == 0)
781  {
782  values[Anum_pg_ts_template_tmpllexize - 1] =
783  get_ts_template_func(defel, Anum_pg_ts_template_tmpllexize);
784  nulls[Anum_pg_ts_template_tmpllexize - 1] = false;
785  }
786  else
787  ereport(ERROR,
788  (errcode(ERRCODE_SYNTAX_ERROR),
789  errmsg("text search template parameter \"%s\" not recognized",
790  defel->defname)));
791  }
792 
793  /*
794  * Validation
795  */
796  if (!OidIsValid(DatumGetObjectId(values[Anum_pg_ts_template_tmpllexize - 1])))
797  ereport(ERROR,
798  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
799  errmsg("text search template lexize method is required")));
800 
801  /*
802  * Looks good, insert
803  */
804  tup = heap_form_tuple(tmplRel->rd_att, values, nulls);
805 
806  CatalogTupleInsert(tmplRel, tup);
807 
808  address = makeTSTemplateDependencies(tup);
809 
810  /* Post creation hook for new text search template */
811  InvokeObjectPostCreateHook(TSTemplateRelationId, tmplOid, 0);
812 
813  heap_freetuple(tup);
814 
815  table_close(tmplRel, RowExclusiveLock);
816 
817  return address;
818 }
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:323
#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:145
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2987
#define DatumGetObjectId(X)
Definition: postgres.h:500
static Datum get_ts_template_func(DefElem *defel, int attnum)
Definition: tsearchcmds.c:648
int errcode(int sqlerrcode)
Definition: elog.c:570
bool superuser(void)
Definition: superuser.c:47
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:638
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
Definition: c.h:603
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:141
uintptr_t Datum
Definition: postgres.h:367
TupleDesc rd_att
Definition: rel.h:84
#define InvalidOid
Definition: postgres_ext.h:36
static ObjectAddress makeTSTemplateDependencies(HeapTuple tuple)
Definition: tsearchcmds.c:691
#define lfirst(lc)
Definition: pg_list.h:190
static Datum values[MAXATTR]
Definition: bootstrap.c:167
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i
char * defname
Definition: parsenodes.h:730
#define TSTemplateOidIndexId
Definition: indexing.h:286
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 1572 of file tsearchcmds.c.

References DatumGetTextPP, elog, ereport, errcode(), errmsg(), ERROR, lappend(), makeDefElem(), makeString(), NIL, palloc(), pfree(), pstrdup(), 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().

1573 {
1574  text *in = DatumGetTextPP(txt); /* in case it's toasted */
1575  List *result = NIL;
1576  int len = VARSIZE_ANY_EXHDR(in);
1577  char *ptr,
1578  *endptr,
1579  *workspace,
1580  *wsptr = NULL,
1581  *startvalue = NULL;
1582  typedef enum
1583  {
1584  CS_WAITKEY,
1585  CS_INKEY,
1586  CS_INQKEY,
1587  CS_WAITEQ,
1588  CS_WAITVALUE,
1589  CS_INSQVALUE,
1590  CS_INDQVALUE,
1591  CS_INWVALUE
1592  } ds_state;
1593  ds_state state = CS_WAITKEY;
1594 
1595  workspace = (char *) palloc(len + 1); /* certainly enough room */
1596  ptr = VARDATA_ANY(in);
1597  endptr = ptr + len;
1598  for (; ptr < endptr; ptr++)
1599  {
1600  switch (state)
1601  {
1602  case CS_WAITKEY:
1603  if (isspace((unsigned char) *ptr) || *ptr == ',')
1604  continue;
1605  if (*ptr == '"')
1606  {
1607  wsptr = workspace;
1608  state = CS_INQKEY;
1609  }
1610  else
1611  {
1612  wsptr = workspace;
1613  *wsptr++ = *ptr;
1614  state = CS_INKEY;
1615  }
1616  break;
1617  case CS_INKEY:
1618  if (isspace((unsigned char) *ptr))
1619  {
1620  *wsptr++ = '\0';
1621  state = CS_WAITEQ;
1622  }
1623  else if (*ptr == '=')
1624  {
1625  *wsptr++ = '\0';
1626  state = CS_WAITVALUE;
1627  }
1628  else
1629  {
1630  *wsptr++ = *ptr;
1631  }
1632  break;
1633  case CS_INQKEY:
1634  if (*ptr == '"')
1635  {
1636  if (ptr + 1 < endptr && ptr[1] == '"')
1637  {
1638  /* copy only one of the two quotes */
1639  *wsptr++ = *ptr++;
1640  }
1641  else
1642  {
1643  *wsptr++ = '\0';
1644  state = CS_WAITEQ;
1645  }
1646  }
1647  else
1648  {
1649  *wsptr++ = *ptr;
1650  }
1651  break;
1652  case CS_WAITEQ:
1653  if (*ptr == '=')
1654  state = CS_WAITVALUE;
1655  else if (!isspace((unsigned char) *ptr))
1656  ereport(ERROR,
1657  (errcode(ERRCODE_SYNTAX_ERROR),
1658  errmsg("invalid parameter list format: \"%s\"",
1659  text_to_cstring(in))));
1660  break;
1661  case CS_WAITVALUE:
1662  if (*ptr == '\'')
1663  {
1664  startvalue = wsptr;
1665  state = CS_INSQVALUE;
1666  }
1667  else if (*ptr == 'E' && ptr + 1 < endptr && ptr[1] == '\'')
1668  {
1669  ptr++;
1670  startvalue = wsptr;
1671  state = CS_INSQVALUE;
1672  }
1673  else if (*ptr == '"')
1674  {
1675  startvalue = wsptr;
1676  state = CS_INDQVALUE;
1677  }
1678  else if (!isspace((unsigned char) *ptr))
1679  {
1680  startvalue = wsptr;
1681  *wsptr++ = *ptr;
1682  state = CS_INWVALUE;
1683  }
1684  break;
1685  case CS_INSQVALUE:
1686  if (*ptr == '\'')
1687  {
1688  if (ptr + 1 < endptr && ptr[1] == '\'')
1689  {
1690  /* copy only one of the two quotes */
1691  *wsptr++ = *ptr++;
1692  }
1693  else
1694  {
1695  *wsptr++ = '\0';
1696  result = lappend(result,
1697  makeDefElem(pstrdup(workspace),
1698  (Node *) makeString(pstrdup(startvalue)), -1));
1699  state = CS_WAITKEY;
1700  }
1701  }
1702  else if (*ptr == '\\')
1703  {
1704  if (ptr + 1 < endptr && ptr[1] == '\\')
1705  {
1706  /* copy only one of the two backslashes */
1707  *wsptr++ = *ptr++;
1708  }
1709  else
1710  *wsptr++ = *ptr;
1711  }
1712  else
1713  {
1714  *wsptr++ = *ptr;
1715  }
1716  break;
1717  case CS_INDQVALUE:
1718  if (*ptr == '"')
1719  {
1720  if (ptr + 1 < endptr && ptr[1] == '"')
1721  {
1722  /* copy only one of the two quotes */
1723  *wsptr++ = *ptr++;
1724  }
1725  else
1726  {
1727  *wsptr++ = '\0';
1728  result = lappend(result,
1729  makeDefElem(pstrdup(workspace),
1730  (Node *) makeString(pstrdup(startvalue)), -1));
1731  state = CS_WAITKEY;
1732  }
1733  }
1734  else
1735  {
1736  *wsptr++ = *ptr;
1737  }
1738  break;
1739  case CS_INWVALUE:
1740  if (*ptr == ',' || isspace((unsigned char) *ptr))
1741  {
1742  *wsptr++ = '\0';
1743  result = lappend(result,
1744  makeDefElem(pstrdup(workspace),
1745  (Node *) makeString(pstrdup(startvalue)), -1));
1746  state = CS_WAITKEY;
1747  }
1748  else
1749  {
1750  *wsptr++ = *ptr;
1751  }
1752  break;
1753  default:
1754  elog(ERROR, "unrecognized deserialize_deflist state: %d",
1755  state);
1756  }
1757  }
1758 
1759  if (state == CS_INWVALUE)
1760  {
1761  *wsptr++ = '\0';
1762  result = lappend(result,
1763  makeDefElem(pstrdup(workspace),
1764  (Node *) makeString(pstrdup(startvalue)), -1));
1765  }
1766  else if (state != CS_WAITKEY)
1767  ereport(ERROR,
1768  (errcode(ERRCODE_SYNTAX_ERROR),
1769  errmsg("invalid parameter list format: \"%s\"",
1770  text_to_cstring(in))));
1771 
1772  pfree(workspace);
1773 
1774  return result;
1775 }
Value * makeString(char *str)
Definition: value.c:53
#define NIL
Definition: pg_list.h:65
#define VARDATA_ANY(PTR)
Definition: postgres.h:348
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define DatumGetTextPP(X)
Definition: fmgr.h:286
Definition: nodes.h:525
int errcode(int sqlerrcode)
Definition: elog.c:570
DefElem * makeDefElem(char *name, Node *arg, int location)
Definition: makefuncs.c:544
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
List * lappend(List *list, void *datum)
Definition: list.c:322
Definition: regguts.h:298
char * text_to_cstring(const text *t)
Definition: varlena.c:204
#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:784
#define elog(elevel,...)
Definition: elog.h:226
Definition: c.h:549
Definition: pg_list.h:50

◆ DropConfigurationMapping()

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

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

1448 {
1449  Form_pg_ts_config tsform;
1450  Oid cfgId;
1451  ScanKeyData skey[2];
1452  SysScanDesc scan;
1453  HeapTuple maptup;
1454  int i;
1455  Oid prsId;
1456  int *tokens;
1457  ListCell *c;
1458 
1459  tsform = (Form_pg_ts_config) GETSTRUCT(tup);
1460  cfgId = tsform->oid;
1461  prsId = tsform->cfgparser;
1462 
1463  tokens = getTokenTypes(prsId, stmt->tokentype);
1464 
1465  i = 0;
1466  foreach(c, stmt->tokentype)
1467  {
1468  Value *val = (Value *) lfirst(c);
1469  bool found = false;
1470 
1471  ScanKeyInit(&skey[0],
1472  Anum_pg_ts_config_map_mapcfg,
1473  BTEqualStrategyNumber, F_OIDEQ,
1474  ObjectIdGetDatum(cfgId));
1475  ScanKeyInit(&skey[1],
1476  Anum_pg_ts_config_map_maptokentype,
1477  BTEqualStrategyNumber, F_INT4EQ,
1478  Int32GetDatum(tokens[i]));
1479 
1480  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1481  NULL, 2, skey);
1482 
1483  while (HeapTupleIsValid((maptup = systable_getnext(scan))))
1484  {
1485  CatalogTupleDelete(relMap, &maptup->t_self);
1486  found = true;
1487  }
1488 
1489  systable_endscan(scan);
1490 
1491  if (!found)
1492  {
1493  if (!stmt->missing_ok)
1494  {
1495  ereport(ERROR,
1496  (errcode(ERRCODE_UNDEFINED_OBJECT),
1497  errmsg("mapping for token type \"%s\" does not exist",
1498  strVal(val))));
1499  }
1500  else
1501  {
1502  ereport(NOTICE,
1503  (errmsg("mapping for token type \"%s\" does not exist, skipping",
1504  strVal(val))));
1505  }
1506  }
1507 
1508  i++;
1509  }
1510 
1511  EventTriggerCollectAlterTSConfig(stmt, cfgId, NULL, 0);
1512 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#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:570
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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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:1227
char * c
void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, Oid cfgId, Oid *dictIds, int ndicts)
#define ereport(elevel, rest)
Definition: elog.h:141
#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:784
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:271
long val
Definition: informix.c:684
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_ts_parser_func()

static Datum get_ts_parser_func ( DefElem defel,
int  attnum 
)
static

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

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

◆ get_ts_template_func()

static Datum get_ts_template_func ( DefElem defel,
int  attnum 
)
static

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

649 {
650  List *funcName = defGetQualifiedName(defel);
651  Oid typeId[4];
652  Oid retTypeId;
653  int nargs;
654  Oid procOid;
655 
656  retTypeId = INTERNALOID;
657  typeId[0] = INTERNALOID;
658  typeId[1] = INTERNALOID;
659  typeId[2] = INTERNALOID;
660  typeId[3] = INTERNALOID;
661  switch (attnum)
662  {
663  case Anum_pg_ts_template_tmplinit:
664  nargs = 1;
665  break;
666  case Anum_pg_ts_template_tmpllexize:
667  nargs = 4;
668  break;
669  default:
670  /* should not be here */
671  elog(ERROR, "unrecognized attribute for text search template: %d",
672  attnum);
673  nargs = 0; /* keep compiler quiet */
674  }
675 
676  procOid = LookupFuncName(funcName, nargs, typeId, false);
677  if (get_func_rettype(procOid) != retTypeId)
678  ereport(ERROR,
679  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
680  errmsg("function %s should return type %s",
681  func_signature_string(funcName, nargs, NIL, typeId),
682  format_type_be(retTypeId))));
683 
684  return ObjectIdGetDatum(procOid);
685 }
#define NIL
Definition: pg_list.h:65
int errcode(int sqlerrcode)
Definition: elog.c:570
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
unsigned int Oid
Definition: postgres_ext.h:31
Oid get_func_rettype(Oid funcid)
Definition: lsyscache.c:1457
#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:2100
#define ereport(elevel, rest)
Definition: elog.h:141
const char * func_signature_string(List *funcname, int nargs, List *argnames, const Oid *argtypes)
Definition: parse_func.c:2014
int16 attnum
Definition: pg_attribute.h:79
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
Definition: pg_list.h:50

◆ getTokenTypes()

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

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

1228 {
1230  LexDescr *list;
1231  int *res,
1232  i,
1233  ntoken;
1234  ListCell *tn;
1235 
1236  ntoken = list_length(tokennames);
1237  if (ntoken == 0)
1238  return NULL;
1239  res = (int *) palloc(sizeof(int) * ntoken);
1240 
1241  if (!OidIsValid(prs->lextypeOid))
1242  elog(ERROR, "method lextype isn't defined for text search parser %u",
1243  prsId);
1244 
1245  /* lextype takes one dummy argument */
1247  (Datum) 0));
1248 
1249  i = 0;
1250  foreach(tn, tokennames)
1251  {
1252  Value *val = (Value *) lfirst(tn);
1253  bool found = false;
1254  int j;
1255 
1256  j = 0;
1257  while (list && list[j].lexid)
1258  {
1259  if (strcmp(strVal(val), list[j].alias) == 0)
1260  {
1261  res[i] = list[j].lexid;
1262  found = true;
1263  break;
1264  }
1265  j++;
1266  }
1267  if (!found)
1268  ereport(ERROR,
1269  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1270  errmsg("token type \"%s\" does not exist",
1271  strVal(val))));
1272  i++;
1273  }
1274 
1275  return res;
1276 }
char * alias
Definition: ts_public.h:28
#define strVal(v)
Definition: value.h:54
int errcode(int sqlerrcode)
Definition: elog.c:570
TSParserCacheEntry * lookup_ts_parser_cache(Oid prsId)
Definition: ts_cache.c:112
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:655
#define ereport(elevel, rest)
Definition: elog.h:141
int lexid
Definition: ts_public.h:27
uintptr_t Datum
Definition: postgres.h:367
#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:784
#define elog(elevel,...)
Definition: elog.h:226
int i
long val
Definition: informix.c:684

◆ GetTSConfigTuple()

static HeapTuple GetTSConfigTuple ( List names)
static

Definition at line 851 of file tsearchcmds.c.

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

Referenced by AlterTSConfiguration().

852 {
853  HeapTuple tup;
854  Oid cfgId;
855 
856  cfgId = get_ts_config_oid(names, true);
857  if (!OidIsValid(cfgId))
858  return NULL;
859 
861 
862  if (!HeapTupleIsValid(tup)) /* should not happen */
863  elog(ERROR, "cache lookup failed for text search configuration %u",
864  cfgId);
865 
866  return tup;
867 }
Oid get_ts_config_oid(List *names, bool missing_ok)
Definition: namespace.c:2671
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:226

◆ makeConfigurationDependencies()

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

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

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

◆ MakeConfigurationMapping()

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

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

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

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

Referenced by DefineTSDictionary().

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

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

Referenced by DefineTSParser().

129 {
131  ObjectAddress myself,
132  referenced;
133 
134  myself.classId = TSParserRelationId;
135  myself.objectId = prs->oid;
136  myself.objectSubId = 0;
137 
138  /* dependency on namespace */
139  referenced.classId = NamespaceRelationId;
140  referenced.objectId = prs->prsnamespace;
141  referenced.objectSubId = 0;
142  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
143 
144  /* dependency on extension */
145  recordDependencyOnCurrentExtension(&myself, false);
146 
147  /* dependencies on functions */
148  referenced.classId = ProcedureRelationId;
149  referenced.objectSubId = 0;
150 
151  referenced.objectId = prs->prsstart;
152  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
153 
154  referenced.objectId = prs->prstoken;
155  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
156 
157  referenced.objectId = prs->prsend;
158  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
159 
160  referenced.objectId = prs->prslextype;
161  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
162 
163  if (OidIsValid(prs->prsheadline))
164  {
165  referenced.objectId = prs->prsheadline;
166  recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
167  }
168 
169  return myself;
170 }
#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:638
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 691 of file tsearchcmds.c.

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

Referenced by DefineTSTemplate().

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

1132 {
1133  Relation relCfg,
1134  relMap;
1135  HeapTuple tup;
1136  ScanKeyData skey;
1137  SysScanDesc scan;
1138 
1139  /* Remove the pg_ts_config entry */
1140  relCfg = table_open(TSConfigRelationId, RowExclusiveLock);
1141 
1143 
1144  if (!HeapTupleIsValid(tup))
1145  elog(ERROR, "cache lookup failed for text search dictionary %u",
1146  cfgId);
1147 
1148  CatalogTupleDelete(relCfg, &tup->t_self);
1149 
1150  ReleaseSysCache(tup);
1151 
1152  table_close(relCfg, RowExclusiveLock);
1153 
1154  /* Remove any pg_ts_config_map entries */
1155  relMap = table_open(TSConfigMapRelationId, RowExclusiveLock);
1156 
1157  ScanKeyInit(&skey,
1158  Anum_pg_ts_config_map_mapcfg,
1159  BTEqualStrategyNumber, F_OIDEQ,
1160  ObjectIdGetDatum(cfgId));
1161 
1162  scan = systable_beginscan(relMap, TSConfigMapIndexId, true,
1163  NULL, 1, &skey);
1164 
1165  while (HeapTupleIsValid((tup = systable_getnext(scan))))
1166  {
1167  CatalogTupleDelete(relMap, &tup->t_self);
1168  }
1169 
1170  systable_endscan(scan);
1171 
1172  table_close(relMap, RowExclusiveLock);
1173 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:226
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define TSConfigMapIndexId
Definition: indexing.h:271
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 508 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().

509 {
510  Relation relation;
511  HeapTuple tup;
512 
513  relation = table_open(TSDictionaryRelationId, RowExclusiveLock);
514 
516 
517  if (!HeapTupleIsValid(tup))
518  elog(ERROR, "cache lookup failed for text search dictionary %u",
519  dictId);
520 
521  CatalogTupleDelete(relation, &tup->t_self);
522 
523  ReleaseSysCache(tup);
524 
525  table_close(relation, RowExclusiveLock);
526 }
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:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:226
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ RemoveTSParserById()

void RemoveTSParserById ( Oid  prsId)

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

296 {
297  Relation relation;
298  HeapTuple tup;
299 
300  relation = table_open(TSParserRelationId, RowExclusiveLock);
301 
303 
304  if (!HeapTupleIsValid(tup))
305  elog(ERROR, "cache lookup failed for text search parser %u", prsId);
306 
307  CatalogTupleDelete(relation, &tup->t_self);
308 
309  ReleaseSysCache(tup);
310 
311  table_close(relation, RowExclusiveLock);
312 }
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:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:226
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ RemoveTSTemplateById()

void RemoveTSTemplateById ( Oid  tmplId)

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

825 {
826  Relation relation;
827  HeapTuple tup;
828 
829  relation = table_open(TSTemplateRelationId, RowExclusiveLock);
830 
832 
833  if (!HeapTupleIsValid(tup))
834  elog(ERROR, "cache lookup failed for text search template %u",
835  tmplId);
836 
837  CatalogTupleDelete(relation, &tup->t_self);
838 
839  ReleaseSysCache(tup);
840 
841  table_close(relation, RowExclusiveLock);
842 }
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:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define elog(elevel,...)
Definition: elog.h:226
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(), buf, cstring_to_text_with_len(), StringInfoData::data, defGetString(), DefElem::defname, ESCAPE_STRING_SYNTAX, initStringInfo(), 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  /* If backslashes appear, force E syntax to determine their handling */
1543  if (strchr(val, '\\'))
1545  appendStringInfoChar(&buf, '\'');
1546  while (*val)
1547  {
1548  char ch = *val++;
1549 
1550  if (SQL_STR_DOUBLE(ch, true))
1551  appendStringInfoChar(&buf, ch);
1552  appendStringInfoChar(&buf, ch);
1553  }
1554  appendStringInfoChar(&buf, '\'');
1555  if (lnext(deflist, l) != NULL)
1556  appendStringInfoString(&buf, ", ");
1557  }
1558 
1559  result = cstring_to_text_with_len(buf.data, buf.len);
1560  pfree(buf.data);
1561  return result;
1562 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10628
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:321
#define ESCAPE_STRING_SYNTAX
Definition: c.h:1086
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
char * defGetString(DefElem *def)
Definition: define.c:49
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
text * cstring_to_text_with_len(const char *s, int len)
Definition: varlena.c:183
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define lfirst(lc)
Definition: pg_list.h:190
#define SQL_STR_DOUBLE(ch, escape_backslash)
Definition: c.h:1083
Definition: c.h:549
char * defname
Definition: parsenodes.h:730
long val
Definition: informix.c:684

◆ verify_dictoptions()

static void verify_dictoptions ( Oid  tmplId,
List dictoptions 
)
static

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

358 {
359  HeapTuple tup;
360  Form_pg_ts_template tform;
361  Oid initmethod;
362 
363  /*
364  * Suppress this test when running in a standalone backend. This is a
365  * hack to allow initdb to create prefab dictionaries that might not
366  * actually be usable in template1's encoding (due to using external files
367  * that can't be translated into template1's encoding). We want to create
368  * them anyway, since they might be usable later in other databases.
369  */
370  if (!IsUnderPostmaster)
371  return;
372 
374  if (!HeapTupleIsValid(tup)) /* should not happen */
375  elog(ERROR, "cache lookup failed for text search template %u",
376  tmplId);
377  tform = (Form_pg_ts_template) GETSTRUCT(tup);
378 
379  initmethod = tform->tmplinit;
380 
381  if (!OidIsValid(initmethod))
382  {
383  /* If there is no init method, disallow any options */
384  if (dictoptions)
385  ereport(ERROR,
386  (errcode(ERRCODE_SYNTAX_ERROR),
387  errmsg("text search template \"%s\" does not accept options",
388  NameStr(tform->tmplname))));
389  }
390  else
391  {
392  /*
393  * Copy the options just in case init method thinks it can scribble on
394  * them ...
395  */
396  dictoptions = copyObject(dictoptions);
397 
398  /*
399  * Call the init method and see if it complains. We don't worry about
400  * it leaking memory, since our command will soon be over anyway.
401  */
402  (void) OidFunctionCall1(initmethod, PointerGetDatum(dictoptions));
403  }
404 
405  ReleaseSysCache(tup);
406 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define PointerGetDatum(X)
Definition: postgres.h:556
int errcode(int sqlerrcode)
Definition: elog.c:570
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:638
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define OidFunctionCall1(functionId, arg1)
Definition: fmgr.h:655
bool IsUnderPostmaster
Definition: globals.c:109
#define ereport(elevel, rest)
Definition: elog.h:141
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1124
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1172
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:784
FormData_pg_ts_template * Form_pg_ts_template
#define elog(elevel,...)
Definition: elog.h:226
#define NameStr(name)
Definition: c.h:609
#define copyObject(obj)
Definition: nodes.h:641