Thread: Functional index adding one
Hi all: I'm trying to create a functional index into column position of token table (see below). I want to make something like: CREATE INDEX token_position_func ON token (position+1); but I get: test=# CREATE INDEX token_position_func test-# ON token (position+1); ERROR: syntax error at or near "+" LINE 2: ON token (position+1); I read that I can do "ON function(column)" but, is there a built-in function in PostgreSQL to do what I want (add one to the value) or have i to build one to make this simple calculation? CREATE TABLE doc( id INT, editorial VARCHAR, CONSTRAINT doc_pk PRIMARY KEY (id) ); CREATE TABLE token ( id INT, id_doc INT, token VARCHAR, position INT, CONSTRAINT foreign_doc FOREIGN KEY (id_do) REFERENCES doc (identificador) ); Regards, Mario Barcala
am Thu, dem 03.07.2008, um 11:50:39 +0200 mailte lbarcala@freeresearch.org folgendes: > Hi all: > > I'm trying to create a functional index into column position of token > table (see below). I want to make something like: > > CREATE INDEX token_position_func > ON token (position+1); > > but I get: > > test=# CREATE INDEX token_position_func > test-# ON token (position+1); > ERROR: syntax error at or near "+" > LINE 2: ON token (position+1); > > I read that I can do "ON function(column)" but, is there a built-in > function in PostgreSQL to do what I want (add one to the value) or have i > to build one to make this simple calculation? Right, write your own function for that, for example: test=# CREATE TABLE token (id int, id_doc int, token text, position int); CREATE TABLE test=*# create function get_pos(int) returns int as $$ declare ret int; begin select into ret position+1 from token where id=$1; return ret; end; $$language plpgsql immutable; CREATE FUNCTION test=*# CREATE INDEX token_position_func ON token (get_pos(position)); CREATE INDEX Andreas -- Andreas Kretschmer Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header) GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net
On Thu, Jul 03, 2008 at 11:50:39AM +0200, lbarcala@freeresearch.org wrote: > test=# CREATE INDEX token_position_func > test-# ON token (position+1); > ERROR: syntax error at or near "+" > LINE 2: ON token (position+1); > > I read that I can do "ON function(column)" but, is there a built-in > function in PostgreSQL to do what I want (add one to the value) or have i > to build one to make this simple calculation? You just want an extra set of brackets; i.e.: CREATE INDEX token_position_func ON token ((position+1)); Should do the trick. Not entirely sure why, but it'll probably have something to do with avoiding ambiguity in the grammar. Sam
<lbarcala@freeresearch.org> writes: > Hi all: > > I'm trying to create a functional index into column position of token > table (see below). I want to make something like: > > CREATE INDEX token_position_func > ON token (position+1); > > but I get: > > test=# CREATE INDEX token_position_func > test-# ON token (position+1); > ERROR: syntax error at or near "+" > LINE 2: ON token (position+1); > I think you just need another set of parentheses: CREATE INDEX token_position_func on (token(position+1)) Unless you're on a very old version of Postgres, I think 7.3 which had functional indexes but not expression indexes. -- Gregory Stark EnterpriseDB http://www.enterprisedb.com Ask me about EnterpriseDB's On-Demand Production Tuning
"Gregory Stark" <stark@enterprisedb.com> writes: > CREATE INDEX token_position_func on (token(position+1)) Ooops, I misread that as if "token" were a function and not the table. Sam Mason had the right syntax. Sorry. -- Gregory Stark EnterpriseDB http://www.enterprisedb.com Ask me about EnterpriseDB's Slony Replication support!
Sam Mason <sam@samason.me.uk> writes: > You just want an extra set of brackets; i.e.: > CREATE INDEX token_position_func ON token ((position+1)); > Should do the trick. Not entirely sure why, but it'll probably have > something to do with avoiding ambiguity in the grammar. Right. The problem is the Berkeley-era decision to put index opclasses into the syntax without any keyword or punctuation, viz create index ... on table (column_name [ opclass_name ]); So something like CREATE INDEX token_position_func ON token (a + b); is ambiguous: is the + an infix operator, or is it a postfix operator and the "b" is to be taken as an opclass name? We hacked around that by requiring parens around expressions. For backwards compatibility with other Berkeley-era syntax, there's a special exception that you can omit the parens when the expression is just a function call. regards, tom lane
On Thu, Jul 03, 2008 at 11:11:26AM -0400, Tom Lane wrote: > Sam Mason <sam@samason.me.uk> writes: > > Not entirely sure why, but it'll probably have > > something to do with avoiding ambiguity in the grammar. > > Right. The problem is the Berkeley-era decision to put index opclasses > into the syntax without any keyword or punctuation, viz > > create index ... on table (column_name [ opclass_name ]); > > So something like > > CREATE INDEX token_position_func ON token (a + b); > > is ambiguous: is the + an infix operator, or is it a postfix operator > and the "b" is to be taken as an opclass name? In this case it seems unambiguous, but in general I can see why. Hysterical raisins cause all sorts of fun! > We hacked around that by requiring parens around expressions. For > backwards compatibility with other Berkeley-era syntax, there's > a special exception that you can omit the parens when the expression is > just a function call. I'm tempted to say "how about putting another example in the page" but it seems to document the issue quite well already. I've never liked to putting comments into the interactive version of the manual, mainly because they disappear with each major version, but how about having the manual link to the wiki? At the moment, the wiki seems somewhat isolated and I never seem to find myself using it. If there were some nice trails in, maybe it would be used more; somewhere like: http://wiki.postgresql.org/wiki/Manual/sql-createindex I wouldn't worry about versioning, just let the authors of the pages deal with versioning issues in ways appropriate to the subject. Or has this idea been dismissed before? Sam