* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.127 2000/10/26 21:35:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.128 2000/10/31 10:22:10 petere Exp $
*
*-------------------------------------------------------------------------
*/
break;
case T_Float:
case T_String:
+ case T_BitString:
newnode->val.str = pstrdup(from->val.str);
break;
default:
case T_Integer:
case T_Float:
case T_String:
+ case T_BitString:
retval = _copyValue(from);
break;
case T_List:
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.77 2000/10/18 16:16:04 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.78 2000/10/31 10:22:10 petere Exp $
*
*-------------------------------------------------------------------------
*/
return a->val.ival == b->val.ival;
case T_Float:
case T_String:
+ case T_BitString:
return strcmp(a->val.str, b->val.str) == 0;
default:
break;
case T_Integer:
case T_Float:
case T_String:
+ case T_BitString:
retval = _equalValue(a, b);
break;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.35 2000/10/05 19:11:27 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.36 2000/10/31 10:22:10 petere Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
return v;
}
+
+/*
+ * makeBitString
+ *
+ * Caller is responsible for passing a palloc'd string.
+ */
+Value *
+makeBitString(char *str)
+{
+ Value *v = makeNode(Value);
+
+ v->type = T_BitString;
+ v->val.str = str;
+ return v;
+}
+
+
/*
* lcons
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.129 2000/10/26 21:35:48 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.130 2000/10/31 10:22:10 petere Exp $
*
* NOTES
* Every (plan) node in POSTGRES has an associated "out" routine which
* representation plus some other information (string length, etc.)
*
*/
-#include <ctype.h>
-
#include "postgres.h"
+#include <ctype.h>
+
#include "access/heapam.h"
#include "access/htup.h"
#include "catalog/pg_type.h"
_outToken(str, value->val.str);
appendStringInfo(str, "\" ");
break;
+ case T_BitString:
+ appendStringInfo(str, " B%s ", value->val.str);
+ break;
default:
elog(NOTICE, "_outValue: don't know how to print type %d ",
value->type);
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.23 2000/06/14 18:17:32 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/read.c,v 1.24 2000/10/31 10:22:10 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
*
*-------------------------------------------------------------------------
*/
+#include "postgres.h"
+
#include <ctype.h>
#include <errno.h>
-#include "postgres.h"
-
#include "nodes/pg_list.h"
#include "nodes/readfuncs.h"
* nodeTokenType -
* returns the type of the node token contained in token.
* It returns one of the following valid NodeTags:
- * T_Integer, T_Float, T_String
+ * T_Integer, T_Float, T_String, T_BitString
* and some of its own:
* RIGHT_PAREN, LEFT_PAREN, PLAN_SYM, AT_SYMBOL, ATOM_TOKEN
*
retval = AT_SYMBOL;
else if (*token == '\"' && length > 1 && token[length - 1] == '\"')
retval = T_String;
+ else if (*token == 'B')
+ retval = T_BitString;
else
retval = ATOM_TOKEN;
return retval;
this_value = (Node *) makeString(debackslash(token + 1, tok_len - 2));
make_dotted_pair_cell = true;
break;
+ case T_BitString:
+ {
+ char * val = palloc(tok_len);
+ /* skip leading 'B'*/
+ strncpy(val, token + 1, tok_len - 1);
+ val[tok_len - 1] = '\0';
+ this_value = (Node *) makeBitString(val);
+ break;
+ }
default:
elog(ERROR, "nodeRead: Bad type %d", type);
this_value = NULL; /* keep compiler happy */
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.201 2000/10/29 16:11:33 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.202 2000/10/31 10:22:10 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
%token UNIONJOIN
/* Special keywords, not in the query language - see the "lex" file */
-%token <str> IDENT, FCONST, SCONST, Op
+%token <str> IDENT, FCONST, SCONST, BITCONST, Op
%token <ival> ICONST, PARAM
/* these are not real. they are here so that they get generated as #define's*/
{
$$ = makeString($1);
}
+ | BITCONST
+ {
+ $$ = makeString($1);
+ }
| ColId
{
$$ = makeString($1);
}
| POSITION '(' position_list ')'
{
+ /* position(A in B) is converted to position(B, A) */
FuncCall *n = makeNode(FuncCall);
- n->funcname = "strpos";
+ n->funcname = "position";
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
}
| SUBSTRING '(' substr_list ')'
{
+ /* substring(A from B for C) is converted to
+ * substring(A, B, C) */
FuncCall *n = makeNode(FuncCall);
- n->funcname = "substr";
+ n->funcname = "substring";
n->args = $3;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->val.val.str = $1;
$$ = (Node *)n;
}
+ | BITCONST
+ {
+ A_Const *n = makeNode(A_Const);
+ n->val.type = T_BitString;
+ n->val.val.str = $1;
+ $$ = (Node *)n;
+ }
/* This rule formerly used Typename,
* but that causes reduce conflicts with subscripted column names.
* Now, separate into ConstTypename and ConstInterval,
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.47 2000/09/29 18:21:36 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_node.c,v 1.48 2000/10/31 10:22:11 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
+#include "utils/varbit.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
typebyval = false;
break;
+ case T_BitString:
+ val = DirectFunctionCall3(zpbit_in,
+ CStringGetDatum(strVal(value)),
+ ObjectIdGetDatum(InvalidOid),
+ Int32GetDatum(-1));
+ typeid = ZPBITOID;
+ typelen = -1;
+ typebyval = false;
+ break;
+
default:
elog(NOTICE, "make_const: unknown type %d", nodeTag(value));
/* FALLTHROUGH */
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.79 2000/10/30 17:54:16 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.80 2000/10/31 10:22:11 petere Exp $
*
*-------------------------------------------------------------------------
*/
* We use exclusive states for quoted strings, extended comments,
* and to eliminate parsing troubles for numeric strings.
* Exclusive states:
- * <xb> binary numeric string - thomas 1997-11-16
+ * <xbit> bit string literal
* <xc> extended C-style comments - thomas 1997-07-12
* <xd> delimited identifiers (double-quoted identifiers) - thomas 1997-10-27
* <xh> hexadecimal numeric string - thomas 1997-11-16
* <xq> quoted strings - thomas 1997-07-30
*/
-%x xb
+%x xbit
%x xc
%x xd
%x xh
%x xq
-/* Binary number
+/* Bit string
*/
-xbstart [bB]{quote}
-xbstop {quote}
-xbinside [^']+
-xbcat {quote}{whitespace_with_newline}{quote}
+xbitstart [bB]{quote}
+xbitstop {quote}
+xbitinside [^']*
+xbitcat {quote}{whitespace_with_newline}{quote}
/* Hexadecimal number
*/
<xc><<EOF>> { elog(ERROR, "Unterminated /* comment"); }
-{xbstart} {
- BEGIN(xb);
+{xbitstart} {
+ BEGIN(xbit);
startlit();
}
-<xb>{xbstop} {
- char* endptr;
-
+<xbit>{xbitstop} {
BEGIN(INITIAL);
- errno = 0;
- yylval.ival = strtol(literalbuf, &endptr, 2);
- if (*endptr != '\0' || errno == ERANGE)
- elog(ERROR, "Bad binary integer input '%s'",
+ if (literalbuf[strspn(literalbuf, "01")] != '\0')
+ elog(ERROR, "invalid bit string input: '%s'",
literalbuf);
- return ICONST;
+ yylval.str = literalbuf;
+ return BITCONST;
}
<xh>{xhinside} |
-<xb>{xbinside} {
+<xbit>{xbitinside} {
addlit(yytext, yyleng);
}
<xh>{xhcat} |
-<xb>{xbcat} {
+<xbit>{xbitcat} {
/* ignore */
}
-<xb><<EOF>> { elog(ERROR, "Unterminated binary integer"); }
+<xbit><<EOF>> { elog(ERROR, "unterminated bit string literal"); }
{xhstart} {
BEGIN(xh);
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.9 2000/08/26 21:53:41 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.10 2000/10/31 10:22:11 petere Exp $
*
*-------------------------------------------------------------------------
*/
/* Negative shift is a shift to the left */
if (shft < 0)
PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
- VarBitPGetDatum(arg),
- Int32GetDatum(-shft)));
+ VarBitPGetDatum(arg),
+ Int32GetDatum(-shft)));
result = (VarBit *) palloc(VARSIZE(arg));
VARATT_SIZEP(result) = VARSIZE(arg);
PG_RETURN_INT32(result);
}
+
+
+
+/* Determines the position of S2 in the bitstring S1 (1-based string).
+ * If S2 does not appear in S1 this function returns 0.
+ * If S2 is of length 0 this function returns 1.
+ */
+Datum
+bitposition(PG_FUNCTION_ARGS)
+{
+ VarBit *substr = PG_GETARG_VARBIT_P(1);
+ VarBit *arg = PG_GETARG_VARBIT_P(0);
+ int substr_length,
+ arg_length,
+ i,
+ is;
+ bits8 *s, /* pointer into substring */
+ *p; /* pointer into arg */
+ bits8 cmp, /* shifted substring byte to compare */
+ mask1, /* mask for substring byte shifted right */
+ mask2, /* mask for substring byte shifted left */
+ end_mask, /* pad mask for last substring byte */
+ arg_mask; /* pad mask for last argument byte */
+ bool is_match;
+
+ /* Get the substring length */
+ substr_length = VARBITLEN(substr);
+ arg_length = VARBITLEN(arg);
+
+ /* Argument has 0 length or substring longer than argument, return 0 */
+ if (arg_length == 0 || substr_length > arg_length)
+ PG_RETURN_INT32(0);
+
+ /* 0-length means return 1 */
+ if (substr_length == 0)
+ PG_RETURN_INT32(1);
+
+ /* Initialise the padding masks */
+ end_mask = BITMASK << VARBITPAD(substr);
+ arg_mask = BITMASK << VARBITPAD(arg);
+ for (i = 0; i < VARBITBYTES(arg) - VARBITBYTES(substr) + 1; i++)
+ {
+ for (is = 0; is < BITS_PER_BYTE; is++) {
+ is_match = true;
+ p = VARBITS(arg) + i;
+ mask1 = BITMASK >> is;
+ mask2 = ~mask1;
+ for (s = VARBITS(substr);
+ is_match && s < VARBITEND(substr); s++)
+ {
+ cmp = *s >> is;
+ if (s == VARBITEND(substr) - 1)
+ {
+ mask1 &= end_mask >> is;
+ if (p == VARBITEND(arg) - 1) {
+ /* Check that there is enough of arg left */
+ if (mask1 & ~arg_mask) {
+ is_match = false;
+ break;
+ }
+ mask1 &= arg_mask;
+ }
+ }
+ is_match = ((cmp ^ *p) & mask1) == 0;
+ if (!is_match)
+ break;
+ // Move on to the next byte
+ p++;
+ if (p == VARBITEND(arg)) {
+ mask2 = end_mask << (BITS_PER_BYTE - is);
+ is_match = mask2 == 0;
+ elog(NOTICE,"S. %d %d em=%2x sm=%2x r=%d",
+ i,is,end_mask,mask2,is_match);
+ break;
+ }
+ cmp = *s << (BITS_PER_BYTE - is);
+ if (s == VARBITEND(substr) - 1)
+ {
+ mask2 &= end_mask << (BITS_PER_BYTE - is);
+ if (p == VARBITEND(arg) - 1) {
+ if (mask2 & ~arg_mask) {
+ is_match = false;
+ break;
+ }
+ mask2 &= arg_mask;
+ }
+ }
+ is_match = ((cmp ^ *p) & mask2) == 0;
+ }
+ /* Have we found a match */
+ if (is_match)
+ PG_RETURN_INT32(i*BITS_PER_BYTE + is + 1);
+ }
+ }
+ PG_RETURN_INT32(0);
+}
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: catversion.h,v 1.53 2000/10/24 03:34:15 tgl Exp $
+ * $Id: catversion.h,v 1.54 2000/10/31 10:22:12 petere Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200010233
+#define CATALOG_VERSION_NO 200010310
#endif
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_proc.h,v 1.170 2000/10/24 20:15:45 petere Exp $
+ * $Id: pg_proc.h,v 1.171 2000/10/31 10:22:12 petere Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
DATA(insert OID = 885 ( btrim PGUID 14 f t t t 1 f 25 "25" 100 0 0 100 "select btrim($1, \' \')" - ));
DESCR("trim both ends of string");
+DATA(insert OID = 936 ( substring PGUID 12 f t t t 3 f 25 "25 23 23" 100 0 0 100 text_substr - ));
+DESCR("return portion of string");
+DATA(insert OID = 937 ( substring PGUID 14 f t t t 2 f 25 "25 23" 100 0 0 100 "select \042substring\042($1, $2, -1)" - ));
+DESCR("return portion of string");
+
/* for multi-byte support */
DATA(insert OID = 1039 ( getdatabaseencoding PGUID 12 f t f t 0 f 19 "0" 100 0 0 100 getdatabaseencoding - ));
DESCR("encoding name of current database");
DESCR("bitwise right shift");
DATA(insert OID = 1679 ( bitcat PGUID 12 f t t t 2 f 1560 "1560 1560" 100 0 0 100 bitcat - ));
DESCR("bitwise concatenation");
-DATA(insert OID = 1680 ( bitsubstr PGUID 12 f t t t 3 f 1560 "1560 23 23" 100 0 0 100 bitsubstr - ));
-DESCR("bitwise field");
+DATA(insert OID = 1680 ( substring PGUID 12 f t t t 3 f 1560 "1560 23 23" 100 0 0 100 bitsubstr - ));
+DESCR("return portion of bitstring");
DATA(insert OID = 1681 ( length PGUID 12 f t t t 1 f 23 "1560" 100 0 0 100 bitlength - ));
DESCR("bitstring length");
DATA(insert OID = 1682 ( octet_length PGUID 12 f t t t 1 f 23 "1560" 100 0 0 100 bitoctetlength - ));
DATA(insert OID = 1688 ( _varbit PGUID 12 f t t t 2 f 1563 "1563 23" 100 0 0 100 _varbit - ));
DESCR("adjust varbit()[] to typmod length");
+DATA(insert OID = 1698 ( position PGUID 12 f t t t 2 f 23 "1560 1560" 100 0 0 100 bitposition - ));
+DESCR("return position of sub-bitstring");
+DATA(insert OID = 1699 ( substring PGUID 14 f t t t 2 f 1560 "1560 23" 100 0 0 100 "select \042substring\042($1, $2, -1)" - ));
+DESCR("return portion of bitstring");
+
+
/* for mac type support */
DATA(insert OID = 436 ( macaddr_in PGUID 12 f t t t 1 f 829 "0" 100 0 0 100 macaddr_in - ));
DESCR("(internal)");
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: nodes.h,v 1.80 2000/10/26 21:38:12 tgl Exp $
+ * $Id: nodes.h,v 1.81 2000/10/31 10:22:12 petere Exp $
*
*-------------------------------------------------------------------------
*/
T_Integer,
T_Float,
T_String,
+ T_BitString,
T_Null,
/*---------------------
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_list.h,v 1.21 2000/10/05 19:11:36 tgl Exp $
+ * $Id: pg_list.h,v 1.22 2000/10/31 10:22:12 petere Exp $
*
*-------------------------------------------------------------------------
*/
extern Value *makeInteger(long i);
extern Value *makeFloat(char *numericStr);
extern Value *makeString(char *str);
+extern Value *makeBitString(char *str);
extern List *lappend(List *list, void *datum);
extern List *lappendi(List *list, int datum);
extern List *lremove(void *elem, List *list);
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: varbit.h,v 1.7 2000/08/26 21:53:40 tgl Exp $
+ * $Id: varbit.h,v 1.8 2000/10/31 10:22:13 petere Exp $
*
*-------------------------------------------------------------------------
*/
extern Datum bitoctetlength(PG_FUNCTION_ARGS);
extern Datum bitfromint4(PG_FUNCTION_ARGS);
extern Datum bittoint4(PG_FUNCTION_ARGS);
+extern Datum bitposition(PG_FUNCTION_ARGS);
#endif