/* * Reduce a trigram (three possibly multi-byte characters) to a trgm, * which is always exactly three bytes. If we have three single-byte * characters, we just use them as-is; otherwise we form a hash value. */ void compact_trigram(trgm *tptr, char *str, int bytelen) { if (bytelen == 3) { CPTRGM(tptr, str); } else { pg_crc32 crc; INIT_LEGACY_CRC32(crc); COMP_LEGACY_CRC32(crc, str, bytelen); FIN_LEGACY_CRC32(crc); /* * use only 3 upper bytes from crc, hope, it's good enough hashing */ CPTRGM(tptr, &crc); } }
/* * Try to read the existing pg_control file. * * This routine is also responsible for updating old pg_control versions * to the current format. (Currently we don't do anything of the sort.) */ static bool ReadControlFile(void) { int fd; int len; char *buffer; pg_crc32 crc; if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0) { /* * If pg_control is not there at all, or we can't read it, the odds * are we've been handed a bad DataDir path, so give up. User can do * "touch pg_control" to force us to proceed. */ fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), progname, XLOG_CONTROL_FILE, strerror(errno)); if (errno == ENOENT) fprintf(stderr, _("If you are sure the data directory path is correct, execute\n" " touch %s\n" "and try again.\n"), XLOG_CONTROL_FILE); exit(1); } /* Use malloc to ensure we have a maxaligned buffer */ buffer = (char *) malloc(PG_CONTROL_SIZE); len = read(fd, buffer, PG_CONTROL_SIZE); if (len < 0) { fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), progname, XLOG_CONTROL_FILE, strerror(errno)); exit(1); } close(fd); if (len >= sizeof(ControlFileData) && ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION) { /* Check the CRC. */ INIT_CRC32C(crc); COMP_CRC32C(crc, buffer, offsetof(ControlFileData, crc)); FIN_CRC32C(crc); if (EQ_LEGACY_CRC32(crc, ((ControlFileData *) buffer)->crc)) { /* Valid data... */ memcpy(&ControlFile, buffer, sizeof(ControlFile)); return true; } /* Check the CRC using old algorithm. */ INIT_LEGACY_CRC32(crc); COMP_LEGACY_CRC32(crc, buffer, offsetof(ControlFileData, crc)); FIN_LEGACY_CRC32(crc); if (EQ_LEGACY_CRC32(crc, ((ControlFileData *) buffer)->crc)) { /* Valid data... */ memcpy(&ControlFile, buffer, sizeof(ControlFile)); return true; } fprintf(stderr, _("%s: pg_control exists but has invalid CRC; proceed with caution\n"), progname); /* We will use the data anyway, but treat it as guessed. */ memcpy(&ControlFile, buffer, sizeof(ControlFile)); guessed = true; return true; } /* Looks like it's a mess. */ fprintf(stderr, _("%s: pg_control exists but is broken or unknown version; ignoring it\n"), progname); return false; }
Datum gtsvector_compress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *retval = entry; if (entry->leafkey) { /* tsvector */ SignTSVector *res; TSVector val = DatumGetTSVector(entry->key); int32 len; int32 *arr; WordEntry *ptr = ARRPTR(val); char *words = STRPTR(val); len = CALCGTSIZE(ARRKEY, val->size); res = (SignTSVector *) palloc(len); SET_VARSIZE(res, len); res->flag = ARRKEY; arr = GETARR(res); len = val->size; while (len--) { pg_crc32 c; INIT_LEGACY_CRC32(c); COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len); FIN_LEGACY_CRC32(c); *arr = *(int32 *) &c; arr++; ptr++; } len = uniqueint(GETARR(res), val->size); if (len != val->size) { /* * there is a collision of hash-function; len is always less than * val->size */ len = CALCGTSIZE(ARRKEY, len); res = (SignTSVector *) repalloc((void *) res, len); SET_VARSIZE(res, len); } /* make signature, if array is too long */ if (VARSIZE(res) > TOAST_INDEX_TARGET) { SignTSVector *ressign; len = CALCGTSIZE(SIGNKEY, 0); ressign = (SignTSVector *) palloc(len); SET_VARSIZE(ressign, len); ressign->flag = SIGNKEY; makesign(GETSIGN(ressign), res); res = ressign; } retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(res), entry->rel, entry->page, entry->offset, FALSE); } else if (ISSIGNKEY(DatumGetPointer(entry->key)) && !ISALLTRUE(DatumGetPointer(entry->key))) { int32 i, len; SignTSVector *res; BITVECP sign = GETSIGN(DatumGetPointer(entry->key)); LOOPBYTE { if ((sign[i] & 0xff) != 0xff) PG_RETURN_POINTER(retval); } len = CALCGTSIZE(SIGNKEY | ALLISTRUE, 0); res = (SignTSVector *) palloc(len); SET_VARSIZE(res, len); res->flag = SIGNKEY | ALLISTRUE; retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(res), entry->rel, entry->page, entry->offset, FALSE); }
int main(int argc, char *argv[]) { ControlFileData ControlFile; int fd; char ControlFilePath[MAXPGPATH]; char *DataDir; pg_crc32 crc; const char *progname; int argno = 1; int targetversion = -1; uint32 tover; set_pglocale_pgservice(argv[0], "gpmodcatversion"); progname = get_progname(argv[0]); if (argc > 1) { argno = 1; if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { usage(progname); exit(0); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { puts("gpmodcatversion (Greenplum Database) " PG_VERSION); exit(0); } if (strcmp(argv[1], "--catversion") == 0) { if (argc < 2) { /* we didn't get the version number */ printf(_("\nA catalog version must be specified.\n\n")); usage(progname); exit(1); } else { char found = 0; for (targetversion = 0; versions[targetversion].gpversion; targetversion++) { if (strcmp(argv[2], versions[targetversion].gpversion) == 0) { found = 1; break; } } if (!found) { printf(_("\n\"%s\" is not a valid version to " "upgrade/downgrade to.\n\n"), argv[2]); usage(progname); exit(1); } argno = 3; } } } if (argc > argno) DataDir = argv[argno]; else DataDir = getenv("PGDATA"); if (DataDir == NULL) { fprintf(stderr, _("%s: no data directory specified\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); usage(progname); exit(1); } snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); #define FLAGS (O_RDWR | O_EXCL | PG_BINARY) if ((fd = open(ControlFilePath, FLAGS, S_IRUSR | S_IWUSR)) == -1) { fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), progname, ControlFilePath, strerror(errno)); exit(2); } if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) { fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), progname, ControlFilePath, strerror(errno)); exit(2); } /* Check the CRC. */ INIT_CRC32C(crc); COMP_CRC32C(crc, &ControlFile, offsetof(ControlFileData, crc)); FIN_CRC32C(crc); if (!EQ_LEGACY_CRC32(crc, ControlFile.crc)) { /* Check the CRC using old algorithm. */ INIT_LEGACY_CRC32(crc); COMP_LEGACY_CRC32(crc, (char *) &ControlFile, offsetof(ControlFileData, crc)); FIN_LEGACY_CRC32(crc); if (!EQ_LEGACY_CRC32(crc, ControlFile.crc)) printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n" "Either the file is corrupt, or it has a different layout than this program\n" "is expecting. The results below are untrustworthy.\n\n")); } printf(_("\nCatalog version number: %u\n"), ControlFile.catalog_version_no); tover = versions[targetversion].vernum; if (tover) { if (ControlFile.state != DB_SHUTDOWNED) { /* only upgrade shutdown systems */ printf(_("\n\nFATAL ERROR\n\n" "Invalid database state for upgrade: %s\n" "Action: shutdown the database and try again.\n"), dbState(ControlFile.state)); close(fd); exit(1); } else if (ControlFile.catalog_version_no == tover) { /* must be something wrong if we want to do this */ printf(_("\n\nWarning\n\n" "Catalog version number is already set to %u\n\n"), tover); close(fd); return 0; } printf(_("New catalog version number: %u\n"), tover); ControlFile.catalog_version_no = tover; /* recalcualte the CRC. */ INIT_CRC32C(crc); COMP_CRC32C(crc, &ControlFile, offsetof(ControlFileData, crc)); FIN_CRC32C(crc); /* INIT_LEGACY_CRC32(crc); COMP_LEGACY_CRC32(crc, (char *) &ControlFile, offsetof(ControlFileData, crc)); FIN_LEGACY_CRC32(crc); */ ControlFile.crc = crc; printf(_("Setting version number to: %u\n"), tover); errno = 0; if (lseek(fd, 0, SEEK_SET) < 0) { printf(_("\n\nFATAL ERROR\n" "could not seek control file: %s\n"), strerror(errno)); close(fd); exit(1); } if (write(fd, &ControlFile, sizeof(ControlFile)) != sizeof(ControlFile)) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; printf(_("\n\nFATAL ERROR\n" "could not write to control file: %s\n"), strerror(errno)); close(fd); exit(1); } if (close(fd)) { printf(_("\n\nFATAL ERROR\n" "could not close control file: %s\n"), strerror(errno)); exit(1); } } return 0; }