Ejemplo n.º 1
0
/*
 * 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);
	}
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
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);
	}
Ejemplo n.º 4
0
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;
}