mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
From: "Denis V. Dmitrienko" <denis@null.net>
What it does: It solves stupid problem with cyrillic charsets IP-based on-fly recoding. take a look at /data/charset.conf for details. You can use any tables for any charset. Tables are from Russian Apache project. Tables in this patch contains also Ukrainian characters. Then run ./configure --enable-recode
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.27 1998/02/10 16:03:46 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.28 1998/02/24 15:19:44 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -16,6 +16,10 @@
|
||||
#include "postgres.h"
|
||||
#include "utils/builtins.h"
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
char *convertstr(char *,int,int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CHAR() and VARCHAR() types are part of the ANSI SQL standard. CHAR()
|
||||
* is for blank-padded string whose length is specified in CREATE TABLE.
|
||||
@@ -84,6 +88,11 @@ bpcharin(char *s, int dummy, int16 atttypmod)
|
||||
if (*r == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
convertstr(result + VARHDRSZ,len,0);
|
||||
#endif
|
||||
|
||||
/* blank pad the string if necessary */
|
||||
for (; i < len; i++)
|
||||
{
|
||||
@@ -110,6 +119,11 @@ bpcharout(char *s)
|
||||
result = (char *) palloc(len + 1);
|
||||
StrNCpy(result, VARDATA(s), len+1); /* these are blank-padded */
|
||||
}
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
convertstr(result,len,1);
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -143,6 +157,10 @@ varcharin(char *s, int dummy, int16 atttypmod)
|
||||
VARSIZE(result) = len;
|
||||
strncpy(VARDATA(result), s, len - VARHDRSZ);
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
convertstr(result + VARHDRSZ,len,0);
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -164,6 +182,11 @@ varcharout(char *s)
|
||||
result = (char *) palloc(len + 1);
|
||||
StrNCpy(result, VARDATA(s), len+1);
|
||||
}
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
convertstr(result,len,1);
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.29 1998/01/07 18:46:54 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.30 1998/02/24 15:19:45 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -157,6 +157,11 @@ textin(char *inputText)
|
||||
VARSIZE(result) = len;
|
||||
|
||||
memmove(VARDATA(result), inputText, len - VARHDRSZ);
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
convertstr(VARDATA(result),len-VARHDRSZ,0);
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
@@ -180,6 +185,11 @@ textout(text *vlena)
|
||||
result = (char *) palloc(len + 1);
|
||||
memmove(result, VARDATA(vlena), len);
|
||||
result[len] = '\0';
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
convertstr(result,len,1);
|
||||
#endif
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.9 1998/01/25 04:07:00 scrappy Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.10 1998/02/24 15:20:16 scrappy Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -51,6 +51,11 @@ extern char *DatabaseName;
|
||||
extern char *UserName;
|
||||
extern char *DatabasePath;
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
unsigned char RecodeForwTable[128];
|
||||
unsigned char RecodeBackTable[128];
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Define USE_ENVIRONMENT to get PGDATA, etc. from environment variables.
|
||||
@@ -258,6 +263,145 @@ SetDatabaseName(char *name)
|
||||
strcpy(DatabaseName, name);
|
||||
}
|
||||
|
||||
#ifdef CYR_RECODE
|
||||
#define MAX_TOKEN 80
|
||||
|
||||
/* Some standard C libraries, including GNU, have an isblank() function.
|
||||
Others, including Solaris, do not. So we have our own.
|
||||
*/
|
||||
static bool
|
||||
isblank(const char c)
|
||||
{
|
||||
return (c == ' ' || c == 9 /* tab */ );
|
||||
}
|
||||
|
||||
static void
|
||||
next_token(FILE *fp, char *buf, const int bufsz)
|
||||
{
|
||||
/*--------------------------------------------------------------------------
|
||||
Grab one token out of fp. Tokens are strings of non-blank
|
||||
characters bounded by blank characters, beginning of line, and end
|
||||
of line. Blank means space or tab. Return the token as *buf.
|
||||
Leave file positioned to character immediately after the token or
|
||||
EOF, whichever comes first. If no more tokens on line, return null
|
||||
string as *buf and position file to beginning of next line or EOF,
|
||||
whichever comes first.
|
||||
--------------------------------------------------------------------------*/
|
||||
int c;
|
||||
char *eb = buf + (bufsz - 1);
|
||||
|
||||
/* Move over inital token-delimiting blanks */
|
||||
while (isblank(c = getc(fp)));
|
||||
|
||||
if (c != '\n')
|
||||
{
|
||||
|
||||
/*
|
||||
* build a token in buf of next characters up to EOF, eol, or
|
||||
* blank.
|
||||
*/
|
||||
while (c != EOF && c != '\n' && !isblank(c))
|
||||
{
|
||||
if (buf < eb)
|
||||
*buf++ = c;
|
||||
c = getc(fp);
|
||||
|
||||
/*
|
||||
* Put back the char right after the token (putting back EOF
|
||||
* is ok)
|
||||
*/
|
||||
}
|
||||
ungetc(c, fp);
|
||||
}
|
||||
*buf = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
read_through_eol(FILE *file)
|
||||
{
|
||||
int c;
|
||||
|
||||
do
|
||||
c = getc(file);
|
||||
while (c != '\n' && c != EOF);
|
||||
}
|
||||
|
||||
void SetCharSet()
|
||||
{
|
||||
FILE *file;
|
||||
char *p,c,eof=false;
|
||||
char *map_file;
|
||||
char buf[MAX_TOKEN];
|
||||
int i;
|
||||
unsigned char FromChar,ToChar;
|
||||
|
||||
for(i=0; i<128; i++)
|
||||
{
|
||||
RecodeForwTable[i] = i+128;
|
||||
RecodeBackTable[i] = i+128;
|
||||
}
|
||||
|
||||
p = getenv("PG_RECODETABLE");
|
||||
if (p && *p != '\0')
|
||||
{
|
||||
map_file = (char *) malloc((strlen(DataDir) +
|
||||
strlen(p)+2)*sizeof(char));
|
||||
sprintf(map_file, "%s/%s", DataDir, p);
|
||||
file = fopen(map_file, "r");
|
||||
if (file == NULL)
|
||||
return;
|
||||
eof=false;
|
||||
while (!eof)
|
||||
{
|
||||
c = getc(file);
|
||||
ungetc(c, file);
|
||||
if (c == EOF)
|
||||
eof = true;
|
||||
else
|
||||
{
|
||||
if (c == '#')
|
||||
read_through_eol(file);
|
||||
else
|
||||
{
|
||||
/* Read the FromChar */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
FromChar = strtoul(buf,0,0);
|
||||
/* Read the ToChar */
|
||||
next_token(file, buf, sizeof(buf));
|
||||
if (buf[0] != '\0')
|
||||
{
|
||||
ToChar = strtoul(buf,0,0);
|
||||
RecodeForwTable[FromChar-128] = ToChar;
|
||||
RecodeBackTable[ToChar-128] = FromChar;
|
||||
}
|
||||
read_through_eol(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
free(map_file);
|
||||
}
|
||||
}
|
||||
|
||||
char* convertstr(unsigned char *buff,int len,int dest)
|
||||
{
|
||||
int i;
|
||||
char *ch=buff;
|
||||
for (i = 0; i < len; i++,buff++)
|
||||
{
|
||||
if (*buff >127)
|
||||
if (dest)
|
||||
*buff = RecodeForwTable[*buff-128];
|
||||
else
|
||||
*buff = RecodeBackTable[*buff-128];
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ----------------
|
||||
* GetPgUserName and SetPgUserName
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user