aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1998-02-24 15:27:04 +0000
committerMarc G. Fournier <scrappy@hub.org>1998-02-24 15:27:04 +0000
commit0227a4e1141ae83ac3ae145fa283ede13e86e23e (patch)
tree587d06ca0b71c88ae2c1ac4a90bd5bba13a5c668 /src/backend/utils
parent96316211c3a1300b304d452e09c726fb775aa502 (diff)
downloadpostgresql-0227a4e1141ae83ac3ae145fa283ede13e86e23e.tar.gz
postgresql-0227a4e1141ae83ac3ae145fa283ede13e86e23e.zip
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
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/varchar.c25
-rw-r--r--src/backend/utils/adt/varlena.c12
-rw-r--r--src/backend/utils/init/miscinit.c146
3 files changed, 180 insertions, 3 deletions
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index a7b6abdaeb1..f3a2df7b94d 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -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);
}
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 1fc611286c5..8d334a2ffd9 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -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);
}
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index fe26cdde864..9bc13907dc2 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -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
*