No necesitas escapar - dentro de las clases de caracteres cuando lo pones en la primera o última posición, porque no se puede leer mal como rango de esa manera:
[\- ] -> [- ] [\d\- ] -> [\d -]
La forma en que lo tienes el límite superior 10 al final es inútil.
Añadir $ al final para no permitir caracteres finales.
O \D para no permitir dígitos finales (pero requiere un dígito que no sea).
O ($|\D) para terminar la cadena allí o tener un seguidor que no sea un dígito.
Juntar:
SELECT '+79637434199' ~ '^(8|\+7)[ -]?(\(?\d{3}\)?[ -]?)[\d -]{7,10}($|\D)'
De lo contrario, su expresión está bien y me funciona en PostgreSQL 9.1.4. No debería hacer ninguna diferencia si lo usa en un WHERE cláusula o en un SELECT lista - a menos que se encuentre con un error con alguna versión anterior (como @kgrittn sugirió en los comentarios).
Si antepongo el literal de cadena con E , puedo provocar el mensaje de error que recibes. Esto no puede explique su problema, porque indicó que la expresión funciona bien como SELECT elemento.
Pero, como se cita a Sherlock Holmes, "cuando se ha excluido lo imposible, lo que quede, por improbable que sea, debe ser la verdad".
Tal vez ejecutó una prueba con standard_conforming_strings = on
y el otro con standard_conforming_strings = off - esta era la interpretación predeterminada de los literales de cadena en versiones anteriores a la 9.1. Tal vez con dos clientes diferentes (que tienen una configuración diferente en cuanto a eso).
Obtenga más información en el capítulo Constantes de cadenas con escapes estilo C en el manual.