PostgreSQL рдореЗрдВ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдирд╛


рд╣реИрд▓реЛ, habracheloveki! рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рд╡рд┐рд╖рдп PostgreSQL рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ред рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо 3 рдбреА рд╡реИрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯреА рд╕реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░, рдСрдкрд░реЗрдЯрд░ рдФрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрд▓рд╛рдХрд╛рд░реЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рд╕реЗ рдЦреБрдж рдХреЛ рдкрд░рд┐рдЪрд┐рдд рдХрд░рдирд╛ рдЕрддрд┐рд╢реНрдпреЛрдХреНрддрд┐рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реА рднрд╛рд╖рд╛ рдореЗрдВ рд╣реЛрдЧрд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╣рд╛рдереА рдорд┐рддреНрд░ рд▓реЗрдЦ рдХреЗ рдЧреНрд░реЗ рддрдХрдиреАрдХреА рдкрд╛рда рдХреЛ рдЙрдЬреНрдЬреНрд╡рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреЗред

рд╡рд┐рд╡рд░рдг



PostgreSQL рдореЗрдВ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рдХрдИ SQL рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ (рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░, рдлрд╝рдВрдХреНрд╢рдВрд╕, рдСрдкрд░реЗрдЯрд░) рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИ, рдЬрд┐рд╕реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдПрдХ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рднрд░реА рд╣реБрдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ) рдФрд░ рдПрдХ рдирд┐рдпрдВрддреНрд░рдг рдлрд╝рд╛рдЗрд▓ рдЬреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд╛рдо, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкрде, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рдВрд╕реНрдХрд░рдг, рдЖрджрд┐ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИред рд╡рд┐рдХрд▓реНрдкред рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реНрдХ рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рддреИрдирд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдирдП рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдорд╛рдЗрдЧреНрд░реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣рдЯрд╛рддреЗ рд╕рдордп, рдирд┐рд░реНрднрд░ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рдореЗрдВ рдПрдХ рдирдпрд╛ рд╡реЗрдХреНрдЯрд░ 3 рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдиреЗ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рднреА рддрд░реНрдХ рд╕реА рдореЗрдВ рд▓рд┐рдЦреЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рднрд░реА рд╣реБрдИ рдЧрдгрд┐рдд 3 рдбреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░реЗрдВрдЧреЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрд╣рд╛рдВ рдпрд╣ рд╕рд╣рдЬ рд╣реЛрдЧрд╛, рд╣рдо рдСрдкрд░реЗрдЯрд░ рдмрдирд╛рдПрдВрдЧреЗред рдЦреИрд░, рдЖрдЦрд┐рд░рдХрд╛рд░, рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рд▓рдкреЗрдЯреЛред

рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрдорд╛рдг



PostgreSQL DBMS рдЖрдкрдХреЛ рдХрдВрдкреЛрдЬрд┐рдЯ рдкреНрд░рдХрд╛рд░, рдПрдиреНрдпреВрдорд░реЗрд╢рди рдЯрд╛рдЗрдк рдФрд░ рд░реЗрдВрдЬ рдкреНрд░рдХрд╛рд░ , рдирдП рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдХреЛ рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬреЛ рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдПрд╕рдХреНрдпреВрдПрд▓ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдирд┐рдЪрд▓реЗ рд╕реНрддрд░ рдХреА рднрд╛рд╖рд╛ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рд╕реА рдореЗрдВред рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХрд╛рд░ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рджреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ: рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯред рдЗрдирдкреБрдЯ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕реА-рд╕реНрдЯреНрд░рд┐рдВрдЧ (рд╢реВрдиреНрдп рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдмрд╛рдЗрдЯреНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА) рдХрд╛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдкреНрд░рдХрд╛рд░ рджреЗрддрд╛ рд╣реИред рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдХрд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╕реА-рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрд╛рд╣рд░реА (рдкрд╛рда) рдкреНрд░рджрд░реНрд╢рди рд╕реЗ рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред

DBMS рдХреА рдУрд░ рд╕реЗ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░:

рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ math3d.c рдореЗрдВ, рд╡реЗрдХреНрдЯрд░ 3, рдЯреЗрдХреНрд╕реНрдЯ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ рдЗрд╕ рдХреЗ рд▓рд┐рдП рдмрд╛рдЗрдирд░реА рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ :
#include <postgres.h> #include <fmgr.h> #include <libpq/pqformat.h> #include <math.h> #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif typedef struct { double x, y, z; } vector3; PG_FUNCTION_INFO_V1(vector3_in); PG_FUNCTION_INFO_V1(vector3_out); PG_FUNCTION_INFO_V1(vector3_recv); PG_FUNCTION_INFO_V1(vector3_send); Datum vector3_in(PG_FUNCTION_ARGS) { char *s = PG_GETARG_CSTRING(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); if (sscanf(s, "(%lf,%lf,%lf)", &(v->x), &(v->y), &(v->z)) != 3) { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("Invalid input syntax for vector3: \"%s\"", s))); } PG_RETURN_POINTER(v); } Datum vector3_out(PG_FUNCTION_ARGS) { vector3 *v = (vector3*)PG_GETARG_POINTER(0); char *s = (char*)palloc(100); snprintf(s, 100, "(%lf,%lf,%lf)", v->x, v->y, v->z); PG_RETURN_CSTRING(s); } Datum vector3_recv(PG_FUNCTION_ARGS) { StringInfo buffer = (StringInfo)PG_GETARG_POINTER(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = pq_getmsgfloat8(buffer); v->y = pq_getmsgfloat8(buffer); v->z = pq_getmsgfloat8(buffer); PG_RETURN_POINTER(v); } Datum vector3_send(PG_FUNCTION_ARGS) { vector3 *v = (vector3*)PG_GETARG_POINTER(0); StringInfoData buffer; pq_begintypsend(&buffer); pq_sendfloat8(&buffer, v->x); pq_sendfloat8(&buffer, v->y); pq_sendfloat8(&buffer, v->z); PG_RETURN_BYTEA_P(pq_endtypsend(&buffer)); } 

рд╣рдо рдЗрд╕ рдмрд╛рдд рд╕реЗ рд╕рд╣рдордд рд╣реИрдВ рдХрд┐ рдЯрд╛рдЗрдк рд╡реЗрдХреНрдЯрд░ 3 рдХрд╛ рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ "рдПрдХреНрд╕ (рд╡рд╛рдИ, рд╡рд╛рдИ, рдЬреЗрдб)" рдХреЗ рд░реВрдк рдореЗрдВ рд╣реЛрдЧрд╛, рдЬрд╣рд╛рдВ рдПрдХреНрд╕, рд╡рд╛рдИ, рдЬреЗрдб, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡реЗрдХреНрдЯрд░ рдХреЗ рдШрдЯрдХ рд╣реИрдВред рд╡реЗрдХреНрдЯрд░ 3_in рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рд╡реЗрдХреНрдЯрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рддрд░реНрдХ рд╕реЗ рдирд┐рдХрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ рд╕реА-рд╕реНрдЯреНрд░рд┐рдВрдЧ, sscanf рдФрд░ рдирд┐рд░реНрдорд┐рдд рд╡реЗрдХреНрдЯрд░ (рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡реЗрдХреНрдЯрд░ 3_рдЖрдЙрдЯ рдореЗрдВ рд╡рд┐рдкрд░реАрдд рдкреНрд░рднрд╛рд╡ рд╣реЛрддрд╛ рд╣реИ - рд╡реЗрдХреНрдЯрд░ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдирд╛ рдФрд░ рдЙрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ред

рдЕрдм рдЪрд▓реЛ рдХрдВрд╕реЛрд▓ рдкрд░ рдЬрд╛рдПрдВ, рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рднрд░реА рд╣реБрдИ math3d рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ $ libdir рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ рдбрд╛рд▓реЗрдВ (рдЬрд┐рд╕реЗ рдЖрдк pg_config --pkglibdir рдХрдорд╛рдВрдб рдЪрд▓рд╛рдХрд░ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ):
 cc -I/usr/local/pgsql/include/server -fpic -c math3d.c cc -shared -L/usr/local/pgsql/lib -lpq -o math3d.so math3d.o cp math3d.so /usr/local/pgsql/lib/ 

рдЕрдм, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рд╡реЗрдХреНрдЯрд░ 3 рдкреНрд░рдХрд╛рд░ рдмрдирд╛рддреЗ рд╣реИрдВ:
 CREATE TYPE vector3; CREATE OR REPLACE FUNCTION vector3_in ( s cstring ) RETURNS vector3 AS 'math3d', 'vector3_in' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_out ( v vector3 ) RETURNS cstring AS 'math3d', 'vector3_out' LANGUAGE C IMMUTABLE STRICT; CREATE FUNCTION vector3_recv ( p internal ) RETURNS vector3 AS 'math3d', 'vector3_recv' LANGUAGE C IMMUTABLE STRICT; CREATE FUNCTION vector3_send ( v vector3 ) RETURNS bytea AS 'math3d', 'vector3_send' LANGUAGE C IMMUTABLE STRICT; CREATE TYPE vector3 ( internallength = 24, input = vector3_in, output = vector3_out, receive = vector3_recv, send = vector3_send ); 

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдлрд╝рдВрдХреНрд╢рди рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдкреНрд░рдХрд╛рд░ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рддреЗ рд╕рдордп, рдорд╛рдкрджрдВрдбреЛрдВ рд╕реЗ рд╣рдо рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдФрд░ рдЗрдирдкреБрдЯ / рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЖрдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред

рдкрд░реАрдХреНрд╖рдг рдЕрдиреБрд░реЛрдз рдЪрд▓рд╛рдПрдБ:
 SELECT '(0.0,1.0,0.0)'::vector3; -- (0.000000,1.000000,0.000000)   vector3 

рд╡реЗрдХреНрдЯрд░ рдСрдкрд░реЗрд╢рди



рдкреНрд░рдХрд╛рд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд╛рда рдлреЙрд░реНрдо рдореЗрдВ рдХрдореА рд╕реЗ рдЕрдзрд┐рдХ рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдпрд╣ рдЕрднреА рддрдХ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реИред рдЪрд▓реЛ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

Math3d.c рдореЗрдВ рдкрд░рд┐рдЪрд╛рд▓рди рд▓рд╛рдЧреВ рдХрд░рдирд╛
 PG_FUNCTION_INFO_V1(vector3_minus); //   PG_FUNCTION_INFO_V1(vector3_add); //   PG_FUNCTION_INFO_V1(vector3_sub); //   PG_FUNCTION_INFO_V1(vector3_mul_left); //     PG_FUNCTION_INFO_V1(vector3_mul_right); //     PG_FUNCTION_INFO_V1(vector3_div_left); //     PG_FUNCTION_INFO_V1(vector3_div_right); //     PG_FUNCTION_INFO_V1(vector3_equal); //     PG_FUNCTION_INFO_V1(vector3_not_equal); //     PG_FUNCTION_INFO_V1(vector3_dot); //   PG_FUNCTION_INFO_V1(vector3_cross); //   PG_FUNCTION_INFO_V1(vector3_length); //   PG_FUNCTION_INFO_V1(vector3_normalize); //   PG_FUNCTION_INFO_V1(vector3_distance); //    Datum vector3_minus(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = -v0->x; v->y = -v0->y; v->z = -v0->z; PG_RETURN_POINTER(v); } Datum vector3_add(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x + v1->x; v->y = v0->y + v1->y; v->z = v0->z + v1->z; PG_RETURN_POINTER(v); } Datum vector3_sub(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x - v1->x; v->y = v0->y - v1->y; v->z = v0->z - v1->z; PG_RETURN_POINTER(v); } Datum vector3_mul_left(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); double k = PG_GETARG_FLOAT8(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x * k; v->y = v0->y * k; v->z = v0->z * k; PG_RETURN_POINTER(v); } Datum vector3_mul_right(PG_FUNCTION_ARGS) { double k = PG_GETARG_FLOAT8(0); vector3 *v0 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = k * v0->x; v->y = k * v0->y; v->z = k * v0->z; PG_RETURN_POINTER(v); } Datum vector3_div_left(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); double k = PG_GETARG_FLOAT8(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x / k; v->y = v0->y / k; v->z = v0->z / k; PG_RETURN_POINTER(v); } Datum vector3_div_right(PG_FUNCTION_ARGS) { double k = PG_GETARG_FLOAT8(0); vector3 *v0 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = k / v0->x; v->y = k / v0->y; v->z = k / v0->z; PG_RETURN_POINTER(v); } Datum vector3_equal(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); bool equal = true; equal &= v0->x == v1->x; equal &= v0->y == v1->y; equal &= v0->z == v1->z; PG_RETURN_BOOL(equal); } Datum vector3_not_equal(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); bool not_equal = false; not_equal |= v0->x != v1->x; not_equal |= v0->y != v1->y; not_equal |= v0->z != v1->z; PG_RETURN_BOOL(not_equal); } Datum vector3_dot(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); double r = v0->x * v1->x + v0->y * v1->y + v0->z * v1->z; PG_RETURN_FLOAT8(r); } Datum vector3_cross(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->y * v1->z - v0->z * v1->y; v->y = v0->z * v1->x - v0->x * v1->z; v->z = v0->x * v1->y - v0->y * v1->x; PG_RETURN_POINTER(v); } Datum vector3_length(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); double len = sqrt(v0->x * v0->x + v0->y * v0->y + v0->z * v0->z); PG_RETURN_FLOAT8(len); } Datum vector3_normalize(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); double len = sqrt(v0->x * v0->x + v0->y * v0->y + v0->z * v0->z); if (len > 0.000001) { v->x = v0->y / len; v->y = v0->z / len; v->z = v0->x / len; } else { v->x = 0.0; v->y = 0.0; v->z = 0.0; } PG_RETURN_POINTER(v); } Datum vector3_distance(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x - v1->x; v->y = v0->y - v1->y; v->z = v0->z - v1->z; double len = sqrt(v->x * v->x + v->y * v->y + v->z * v->z); pfree(v); PG_RETURN_FLOAT8(len); } 


рдореБрдЭреЗ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рд╣реИ рдХрд┐ рдкрд▓реНрд▓реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдореЗрдореЛрд░реА рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрд░рдорд╢рдГ pfree рдореБрдХреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рд╡реЗрдХреНрдЯрд░ 3_mul_left / рд╡реЗрдХреНрдЯрд░3_mul_right рдФрд░ рд╡реЗрдХреНрдЯрд░3_div_left / рд╡реЗрдХреНрдЯрд░3_div_right рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрд╛рдж рдореЗрдВ рдХреНрдпреЛрдВ рд╕рдордЭрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рд╣рдо рдирдП рд╕рддреНрд░ рдореЗрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ math3d.so рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдмрдирд╛рддреЗ рд╣реИрдВ, рддрд╛рдХрд┐ PostgreSQL рд╕рд░реНрд╡рд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ:

SQL рдХреЛрдб рдСрдкрд░реЗрд╢рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП
 CREATE OR REPLACE FUNCTION vector3_minus ( v0 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_minus' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_add ( v0 vector3, v1 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_add' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_sub ( v0 vector3, v1 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_sub' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_mul_left ( v0 vector3, k double precision ) RETURNS vector3 AS 'math3d', 'vector3_mul_left' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_mul_right ( k double precision, v0 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_mul_right' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_div_left ( v0 vector3, k double precision ) RETURNS vector3 AS 'math3d', 'vector3_div_left' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_div_right ( k double precision, v0 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_div_right' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_equal ( v0 vector3, v1 vector3 ) RETURNS boolean AS 'math3d', 'vector3_equal' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_not_equal ( v0 vector3, v1 vector3 ) RETURNS boolean AS 'math3d', 'vector3_not_equal' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_dot ( v0 vector3, v1 vector3 ) RETURNS double precision AS 'math3d', 'vector3_dot' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_cross ( v0 vector3, v1 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_cross' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION length ( v0 vector3 ) RETURNS double precision AS 'math3d', 'vector3_length' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION normalize ( v0 vector3 ) RETURNS vector3 AS 'math3d', 'vector3_normalize' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION distance ( v0 vector3, v1 vector3 ) RETURNS double precision AS 'math3d', 'vector3_distance' LANGUAGE C IMMUTABLE STRICT; 


рдЕрдм рдЖрдк рд╡реЗрдХреНрдЯрд░ рдкрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдСрдкрд░реЗрд╢рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 SELECT vector3_add ( '(0.0,1.0,0.0)'::vector3, '(0.5,0.5,0.0)'::vector3 ); -- (0.500000,1.500000,0.000000) SELECT vector3_mul_right ( 5.0, '(0.2,0.2,1.33)'::vector3 ); -- (1.000000,1.000000,6.650000) SELECT vector3_cross ( '(1.0,0.0,0.0)'::vector3, '(0.0,1.0,0.0)'::vector3 ); -- (0.000000,0.000000,1.000000) SELECT length ( '(0.705,0.705,0.0)'::vector3 ); -- 0.9970206 

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд▓рдЧрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡реЗрдХреНрдЯрд░ рджреНрд╡рд╛рд░рд╛ рд╕реНрдХреЗрд▓рд░ рдХреЛ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ 5.0 * '(0.2,0.2,1.33)' :: рд╡реЗрдХреНрдЯрд░ 3 рдЕрдзрд┐рдХ рд╕рд╣рдЬ рд╣реЛрдЧрд╛ред рдЪрд▓реЛ рдЗрд╕рдХреЗ рд▓рд┐рдП рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдмрдпрд╛рди



PostgreSQL рдореЗрдВ рд╡рд░реНрдгреЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрдердиреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рд╣реИ - * * / <> = ~! @ #% ^ & | `? 63 рдХреА рдЕрдзрд┐рдХрддрдо рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рдеред рд╡реЗ рдПрдХрд╛рддреНрдордХ рдпрд╛ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рд╣реИрдВред рдЖрдк рдУрд╡рд░рд▓реЛрдб рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рд╣реА рдирд╛рдо рд╣реЛ рд▓реЗрдХрд┐рди рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реНрдХ рд╣реЛрдВред рдпрд╣рд╛рдБ рдСрдкрд░реЗрдЯрд░ рдХреЗ рдХреБрдЫ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдорд╛рдирджрдВрдб рд╣реИрдВ ( рдПрдХрд░реА рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рд▓реЗрд░рдЧ рдпрд╛ рд░рд╛рдЗрдЯрд░реНрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ):

рдЖрдЗрдП рдХреБрдЫ рдСрдкрд░реЗрдЯрд░ рдмрдирд╛рдПрдВ:
рдХрдерди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП SQL рдХреЛрдб
 --   CREATE OPERATOR - ( rightarg = vector3, procedure = vector3_minus ); --   CREATE OPERATOR + ( leftarg = vector3, rightarg = vector3, procedure = vector3_add, commutator = + ); --   CREATE OPERATOR - ( leftarg = vector3, rightarg = vector3, procedure = vector3_sub ); --     CREATE OPERATOR * ( leftarg = vector3, rightarg = double precision, procedure = vector3_mul_left ); --     CREATE OPERATOR * ( leftarg = double precision, rightarg = vector3, procedure = vector3_mul_right ); --     CREATE OPERATOR / ( leftarg = vector3, rightarg = double precision, procedure = vector3_div_left ); --     CREATE OPERATOR / ( leftarg = double precision, rightarg = vector3, procedure = vector3_div_right ); --     CREATE OPERATOR = ( leftarg = vector3, rightarg = vector3, procedure = vector3_equal ); --     CREATE OPERATOR != ( leftarg = vector3, rightarg = vector3, procedure = vector3_not_equal ); --   CREATE OPERATOR * ( leftarg = vector3, rightarg = vector3, procedure = vector3_dot commutator = ); --   CREATE OPERATOR ** ( leftarg = vector3, rightarg = vector3, procedure = vector3_cross ); 


рдФрд░ рдЙрдирдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:
 SELECT '(0.0,1.0,0.0)'::vector3 + '(0.5,0.5,0.0)'::vector3; -- (0.500000,1.500000,0.000000) SELECT 5.0 * '(0.2,0.2,1.33)'::vector3; -- (1.000000,1.000000,6.650000) SELECT '(1.0,0.5,0.1)'::vector3 * '(0.707,0.707,0.707)'::vector3; -- 1.1312 SELECT '(1.0,0.0,0.0)'::vector3 ** '(0.0,1.0,0.0)'::vector3; -- (0.000000,0.000000,1.000000) 

рдкрд╣рд▓реЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИред рд╡реИрд╕реЗ, рд╣рдордиреЗ рд╕реНрдХреЗрд▓рд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдХ рддрд░реНрдХ рдХреЗ рд╕рд╛рде рдЧреБрдгрд╛ рдХреЗ рд▓рд┐рдП рджреЛ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХреА, рдЗрд╕ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЬрдм рд╕реНрдХреЗрд▓рд░ рдСрдкрд░реЗрдЯрд░ рдХреЗ рдмрд╛рдИрдВ рдУрд░ рд╣реИ рдФрд░ рдЬрдм рдпрд╣ рджрд╛рдИрдВ рдУрд░ рд╣реИред рдФрд░ рдЗрд╕реА рддрд░рд╣ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд▓рд┐рдПред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рд╡реЗрдХреНрдЯрд░ 3_mul_left / рд╡реЗрдХреНрдЯрд░3_mul_right рдФрд░ рд╡реЗрдХреНрдЯрд░3_div_left / рд╡реЗрдХреНрдЯрд░3_div_right рдХреЗ рдЬреЛрдбрд╝реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╕рд╡рд╛рд▓ рдЙрда рд╕рдХрддрд╛ рд╣реИ: рд╡реЗрдХреНрдЯрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ? рдХреЛрдИ рднреА рддреАрди C- рдХрд╛рд░реНрдп рд╡реЗрдХреНрдЯрд░ 3_x, рд╡реЗрдХреНрдЯрд░ 3_y рдФрд░ рд╡реЗрдХреНрдЯрд░ 3_z рдШреЛрд╖рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдХ рдХреЛ рд▓реМрдЯрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдПрдХ рдмреЗрд╣рддрд░ рддрд░реАрдХрд╛ рд╣реИред

рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдЯрд╛рдЗрдк рдХрд░реЗрдВ



PostgreSQL рдореЗрдВ рдПрдХ рдФрд░ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╕реНрдЯрдо рдХрд▓рд╛рдХрд╛рд░реЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реИред рдпрджрд┐ рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░реЛрдВ рдореЗрдВ рдПрдХ рд╣реА рдЖрдВрддрд░рд┐рдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд╛рд░реНрдЪрд░ рдФрд░ рдкрд╛рда) рд╣реИ, рддреЛ рдЯрд╛рдЗрдк рд░реВрдкрд╛рдВрддрд░рдг рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдЕрдиреНрдпрдерд╛, рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рд▓реМрдЯрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рд╕рдореЗрдВ рдХрд▓рд╛рдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕реЗ рддреАрди рдорд╛рдкрджрдВрдбреЛрдВ рддрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:

рдПрдХ рдХрд▓рд╛рдХрд╛рд░ рдХреЗрд╡рд▓ рдПрдХ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╕рдВрджрд░реНрдн рдпрд╛ рдХрд┐рд╕реА рднреА рд╕рдВрджрд░реНрдн рдореЗрдВ рднрд╛рдЧ рд▓реЗ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╡реНрдпрд╡рд╣рд╛рд░ AS ASIGNIGNMENT рдФрд░ AS IMPLICIT рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред INOUT рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд▓рд╛рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП I / O рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдирдП рдорд┐рд╢реНрд░рд┐рдд рдкреНрд░рдХрд╛рд░ рд╡реЗрдХреНрдЯрд░ 3 рд╕реА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВ рд╡реЗрдХреНрдЯрд░ 3 (рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд):
 CREATE TYPE vector3c AS ( x double precision, y double precision, z double precision ); CREATE OR REPLACE FUNCTION vector3_cast_vector3c ( v0 vector3 ) RETURNS vector3c AS $BODY$ DECLARE s text[]; v vector3c; BEGIN s := string_to_array ( trim ( BOTH '()' FROM v0::text ), ',' ); vx := s[1]; vy := s[2]; vz := s[3]; RETURN v; END $BODY$ LANGUAGE plpgsql IMMUTABLE; CREATE OR REPLACE FUNCTION vector3c_cast_vector3 ( v0 vector3c ) RETURNS vector3 AS $BODY$ DECLARE v vector3; BEGIN v := v0::text; RETURN v; END $BODY$ LANGUAGE plpgsql IMMUTABLE; CREATE CAST ( vector3 AS vector3c ) WITH FUNCTION vector3_cast_vector3c ( v0 vector3 ) AS IMPLICIT; CREATE CAST ( vector3c AS vector3 ) WITH FUNCTION vector3c_cast_vector3 ( v0 vector3c ) AS IMPLICIT; 

рд╡реЗрдХреНрдЯрд░ 3_cast_vector3c рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ , рд╣рдо рдкрд╣рд▓реЗ рд╡реЗрдХреНрдЯрд░ 3 рдХреЛ рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рдкрд╣рд▓реЗ рдФрд░ рдЖрдЦрд┐рд░реА рдХреЛрд╖реНрдардХ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░, рдЕрд▓реНрдкрд╡рд┐рд░рд╛рдо рд╡рд┐рднрд╛рдЬрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рддреАрди рддрддреНрд╡реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рд╣рдо рд╡реЗрдХреНрдЯрд░ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВред рд╡реЗрдХреНрдЯрд░ 3c_cast_vector3 рдореЗрдВ , рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╡реЗрдХреНрдЯрд░ 3 рд╕реА рдХреЛ рддреБрд░рдВрдд рдкрд╛рда рдореЗрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ рд╡реЗрдХреНрдЯрд░ 3 рдореЗрдВ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ (рд╡реЗрдХреНрдЯрд░ 3 рд╕реА рдФрд░ рд╡реЗрдХреНрдЯрд░ 3 рдХреЗ рд▓рд┐рдП рдкрд╛рда рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рд╕рдорд╛рди рд░реВрдк рд╣реИ)ред

рдкреНрд░рдХрд╛рд░ рд░реВрдкрд╛рдВрддрд░рдг рдЬрд╛рдВрдЪреЗрдВ:
 SELECT ('(0.1,1.0,0.5)'::vector3)::vector3c; -- (0.1,1,0.5) SELECT ('(0.707,0.0,0.0)'::vector3c)::vector3; -- (0.707000,0.000000,0.000000) 


рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрдирд╛рдПрдВ



рдЬрдм рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╣рдорд╛рд░реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИред рдЪрд▓реЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рднреА рд╕реА-рдХреЛрдб рдЗрдХрдЯреНрдард╛ рдХрд░рддреЗ рд╣реИрдВ:
Math3d.c рдлрд╝рд╛рдЗрд▓ (рдбрд╛рдпрдиреЗрдорд┐рдХ рд▓реЛрдб рдХрд┐рдП рдЧрдП math3d рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб)
 #include <postgres.h> #include <fmgr.h> #include <libpq/pqformat.h> #include <math.h> #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif // types typedef struct { double x, y, z; } vector3; // declarations PG_FUNCTION_INFO_V1(vector3_in); PG_FUNCTION_INFO_V1(vector3_out); PG_FUNCTION_INFO_V1(vector3_recv); PG_FUNCTION_INFO_V1(vector3_send); PG_FUNCTION_INFO_V1(vector3_minus); PG_FUNCTION_INFO_V1(vector3_add); PG_FUNCTION_INFO_V1(vector3_sub); PG_FUNCTION_INFO_V1(vector3_mul_left); PG_FUNCTION_INFO_V1(vector3_mul_right); PG_FUNCTION_INFO_V1(vector3_div_left); PG_FUNCTION_INFO_V1(vector3_div_right); PG_FUNCTION_INFO_V1(vector3_equal); PG_FUNCTION_INFO_V1(vector3_not_equal); PG_FUNCTION_INFO_V1(vector3_dot); PG_FUNCTION_INFO_V1(vector3_cross); PG_FUNCTION_INFO_V1(vector3_length); PG_FUNCTION_INFO_V1(vector3_normalize); PG_FUNCTION_INFO_V1(vector3_distance); // implementation Datum vector3_in(PG_FUNCTION_ARGS) { char *s = PG_GETARG_CSTRING(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); if (sscanf(s, "(%lf,%lf,%lf)", &(v->x), &(v->y), &(v->z)) != 3) { ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("Invalid input syntax for vector3: \"%s\"", s))); } PG_RETURN_POINTER(v); } Datum vector3_out(PG_FUNCTION_ARGS) { vector3 *v = (vector3*)PG_GETARG_POINTER(0); char *s = (char*)palloc(100); snprintf(s, 100, "(%lf,%lf,%lf)", v->x, v->y, v->z); PG_RETURN_CSTRING(s); } Datum vector3_recv(PG_FUNCTION_ARGS) { StringInfo buffer = (StringInfo)PG_GETARG_POINTER(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = pq_getmsgfloat8(buffer); v->y = pq_getmsgfloat8(buffer); v->z = pq_getmsgfloat8(buffer); PG_RETURN_POINTER(v); } Datum vector3_send(PG_FUNCTION_ARGS) { vector3 *v = (vector3*)PG_GETARG_POINTER(0); StringInfoData buffer; pq_begintypsend(&buffer); pq_sendfloat8(&buffer, v->x); pq_sendfloat8(&buffer, v->y); pq_sendfloat8(&buffer, v->z); PG_RETURN_BYTEA_P(pq_endtypsend(&buffer)); } Datum vector3_minus(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = -v0->x; v->y = -v0->y; v->z = -v0->z; PG_RETURN_POINTER(v); } Datum vector3_add(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x + v1->x; v->y = v0->y + v1->y; v->z = v0->z + v1->z; PG_RETURN_POINTER(v); } Datum vector3_sub(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x - v1->x; v->y = v0->y - v1->y; v->z = v0->z - v1->z; PG_RETURN_POINTER(v); } Datum vector3_mul_left(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); double k = PG_GETARG_FLOAT8(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x * k; v->y = v0->y * k; v->z = v0->z * k; PG_RETURN_POINTER(v); } Datum vector3_mul_right(PG_FUNCTION_ARGS) { double k = PG_GETARG_FLOAT8(0); vector3 *v0 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = k * v0->x; v->y = k * v0->y; v->z = k * v0->z; PG_RETURN_POINTER(v); } Datum vector3_div_left(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); double k = PG_GETARG_FLOAT8(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x / k; v->y = v0->y / k; v->z = v0->z / k; PG_RETURN_POINTER(v); } Datum vector3_div_right(PG_FUNCTION_ARGS) { double k = PG_GETARG_FLOAT8(0); vector3 *v0 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = k / v0->x; v->y = k / v0->y; v->z = k / v0->z; PG_RETURN_POINTER(v); } Datum vector3_equal(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); bool equal = true; equal &= v0->x == v1->x; equal &= v0->y == v1->y; equal &= v0->z == v1->z; PG_RETURN_BOOL(equal); } Datum vector3_not_equal(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); bool not_equal = false; not_equal |= v0->x != v1->x; not_equal |= v0->y != v1->y; not_equal |= v0->z != v1->z; PG_RETURN_BOOL(not_equal); } Datum vector3_dot(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); double r = v0->x * v1->x + v0->y * v1->y + v0->z * v1->z; PG_RETURN_FLOAT8(r); } Datum vector3_cross(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->y * v1->z - v0->z * v1->y; v->y = v0->z * v1->x - v0->x * v1->z; v->z = v0->x * v1->y - v0->y * v1->x; PG_RETURN_POINTER(v); } Datum vector3_length(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); double len = sqrt(v0->x * v0->x + v0->y * v0->y + v0->z * v0->z); PG_RETURN_FLOAT8(len); } Datum vector3_normalize(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v = (vector3*)palloc(sizeof(vector3)); double len = sqrt(v0->x * v0->x + v0->y * v0->y + v0->z * v0->z); if (len > 0.000001) { v->x = v0->y / len; v->y = v0->z / len; v->z = v0->x / len; } else { v->x = 0.0; v->y = 0.0; v->z = 0.0; } PG_RETURN_POINTER(v); } Datum vector3_distance(PG_FUNCTION_ARGS) { vector3 *v0 = (vector3*)PG_GETARG_POINTER(0); vector3 *v1 = (vector3*)PG_GETARG_POINTER(1); vector3 *v = (vector3*)palloc(sizeof(vector3)); v->x = v0->x - v1->x; v->y = v0->y - v1->y; v->z = v0->z - v1->z; double len = sqrt(v->x * v->x + v->y * v->y + v->z * v->z); pfree(v); PG_RETURN_FLOAT8(len); } 


рдЖрдЗрдП рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рднрд░реА рд╣реБрдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд╕реНрд╡рдпрдВ рдПрдХрддреНрд░рд┐рдд рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ PGDIR / lib рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдбрд╛рд▓реЗрдВред рдЗрд╕реА рддрд░рд╣, SQL рдХреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╛рдЗрд▓ рдмрдирд╛рдПрдВ:
Math3d рдлрд╝рд╛рдЗрд▓ 1.0.sql (math3d рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд▓рд┐рдП SQL рд╕реНрдХреНрд░рд┐рдкреНрдЯ) рд╣реИ
 CREATE TYPE vector3; CREATE OR REPLACE FUNCTION vector3_in ( s cstring ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_in' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_out ( v vector3 ) RETURNS cstring AS 'MODULE_PATHNAME', 'vector3_out' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_recv ( p internal ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_recv' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION vector3_send ( v vector3 ) RETURNS bytea AS 'MODULE_PATHNAME', 'vector3_send' LANGUAGE C IMMUTABLE STRICT; CREATE TYPE vector3 ( internallength = 24, input = vector3_in, output = vector3_out, receive = vector3_recv, send = vector3_send ); CREATE OR REPLACE FUNCTION vector3_minus ( v0 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_minus' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR - ( rightarg = vector3, procedure = vector3_minus ); CREATE OR REPLACE FUNCTION vector3_add ( v0 vector3, v1 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_add' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR + ( leftarg = vector3, rightarg = vector3, procedure = vector3_add, commutator = + ); CREATE OR REPLACE FUNCTION vector3_sub ( v0 vector3, v1 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_sub' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR - ( leftarg = vector3, rightarg = vector3, procedure = vector3_sub ); CREATE OR REPLACE FUNCTION vector3_mul_left ( v0 vector3, k double precision ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_mul_left' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR * ( leftarg = vector3, rightarg = double precision, procedure = vector3_mul_left, commutator = * ); CREATE OR REPLACE FUNCTION vector3_mul_right ( k double precision, v0 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_mul_right' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR * ( leftarg = double precision, rightarg = vector3, procedure = vector3_mul_right, commutator = * ); CREATE OR REPLACE FUNCTION vector3_div_left ( v0 vector3, k double precision ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_div_left' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR / ( leftarg = vector3, rightarg = double precision, procedure = vector3_div_left ); CREATE OR REPLACE FUNCTION vector3_div_right ( k double precision, v0 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_div_right' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR / ( leftarg = double precision, rightarg = vector3, procedure = vector3_div_right ); CREATE OR REPLACE FUNCTION vector3_equal ( v0 vector3, v1 vector3 ) RETURNS boolean AS 'MODULE_PATHNAME', 'vector3_equal' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR = ( leftarg = vector3, rightarg = vector3, procedure = vector3_equal ); CREATE OR REPLACE FUNCTION vector3_not_equal ( v0 vector3, v1 vector3 ) RETURNS boolean AS 'MODULE_PATHNAME', 'vector3_not_equal' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR != ( leftarg = vector3, rightarg = vector3, procedure = vector3_not_equal ); CREATE OR REPLACE FUNCTION vector3_dot ( v0 vector3, v1 vector3 ) RETURNS double precision AS 'MODULE_PATHNAME', 'vector3_dot' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR * ( leftarg = vector3, rightarg = vector3, procedure = vector3_dot, commutator = * ); CREATE OR REPLACE FUNCTION vector3_cross ( v0 vector3, v1 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_cross' LANGUAGE C IMMUTABLE STRICT; CREATE OPERATOR ** ( leftarg = vector3, rightarg = vector3, procedure = vector3_cross, commutator = ** ); CREATE OR REPLACE FUNCTION length ( v0 vector3 ) RETURNS double precision AS 'MODULE_PATHNAME', 'vector3_length' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION normalize ( v0 vector3 ) RETURNS vector3 AS 'MODULE_PATHNAME', 'vector3_normalize' LANGUAGE C IMMUTABLE STRICT; CREATE OR REPLACE FUNCTION distance ( v0 vector3, v1 vector3 ) RETURNS double precision AS 'MODULE_PATHNAME', 'vector3_distance' LANGUAGE C IMMUTABLE STRICT; CREATE TYPE vector3c AS ( x double precision, y double precision, z double precision ); CREATE OR REPLACE FUNCTION vector3_cast_vector3c ( v0 vector3 ) RETURNS vector3c AS $BODY$ DECLARE s text[]; v vector3c; BEGIN s := string_to_array ( trim ( BOTH '()' FROM v0::text ), ',' ); vx := s[1]; vy := s[2]; vz := s[3]; RETURN v; END $BODY$ LANGUAGE plpgsql IMMUTABLE; CREATE OR REPLACE FUNCTION vector3c_cast_vector3 ( v0 vector3c ) RETURNS vector3 AS $BODY$ DECLARE v vector3; BEGIN v := v0::text; RETURN v; END $BODY$ LANGUAGE plpgsql IMMUTABLE; CREATE CAST ( vector3 AS vector3c ) WITH FUNCTION vector3_cast_vector3c ( v0 vector3 ) AS IMPLICIT; CREATE CAST ( vector3c AS vector3 ) WITH FUNCTION vector3c_cast_vector3 ( v0 vector3c ) AS IMPLICIT; 


рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдлреЙрд░реНрдо рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП <extensionname> - <version> .sqlред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдВрд╕реНрдХрд░рдг рд╣реЛрдЧрд╛ 1.0ред рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЛ PGDIR / рд╢реЗрдпрд░ / рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ рд░рдЦреЗрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛рдУрдВ рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рднрд░реА рд╣реБрдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдирд╛рдо MODULE_PATHNAME рдЪрд░ рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рдирд┐рдпрдВрддреНрд░рдг рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:
 # math3d extension comment = '3D mathematics' default_version = '1.0' module_pathname = '$libdir/math3d' relocatable = true 

рдЙрдкрд▓рдмреНрдз рд╡рд┐рдХрд▓реНрдкреЛрдВ рдореЗрдВ рд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИрдВ:

рдирд┐рдпрдВрддреНрд░рдг рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдЗрд╕ рд░реВрдк рдореЗрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП <extension_name> .control, рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ math3d.controlред рдЗрд╕реЗ рдкреАрдЬреАрдбреАрдЖрдИрдЖрд░ / рд╢реЗрдпрд░ / рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ рдбрд╛рд▓реЗрдВред рдореВрд▓ рд░реВрдк рд╕реЗ, рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред

рдПрдХ рдирдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рдмрдирд╛рдПрдВ, рдЙрд╕рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ рдФрд░ рд╣рдорд╛рд░реЗ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рд▓реЛрдб рдХрд░реЗрдВ:
 CREATE EXTENSION math3d; 

рдпрджрд┐ рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рд╣рдорд╛рд░реЗ рдирдП рдкреНрд░рдХрд╛рд░ рд╡реЗрдХреНрдЯрд░ 3 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдЗрд╕реЗ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдпрд╛ рд╕рдордЧреНрд░ рдкреНрд░рдХрд╛рд░ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ, рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдФрд░ рдЕрдиреНрдп рдЬрдЧрд╣реЛрдВ рдкрд░ред рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдФрд░ рдЖрд╢реНрд░рд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╣рдЯрд╛рдирд╛ рдПрдХ рд╕рдорд╛рди рдХрдорд╛рдВрдб рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
 DROP EXTENSION math3d; 

рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддрд╛рд▓рд┐рдХрд╛рдПрдБ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ рдЬреЛ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реНрдерд╛рдкрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╕рдВрд╢реЛрдзрд┐рдд рд╣реЛрддреА рд╣реИрдВред рдЪреВрдВрдХрд┐ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рдирд┐рдпрдорд┐рдд рдЯреЗрдмрд▓ рдФрд░ рдЗрд╕рдХрд╛ рдбреЗрдЯрд╛ рдбрдВрдк рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдЯреЗрдмрд▓ рдХреЛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
 CREATE TABLE user_setting ( username text, key text, value text ); SELECT pg_catalog.pg_extension_config_dump ( 'user_setting', '' ); 

рджреВрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ pg_catalog.pg_extension_config_dump рдореЗрдВ рдПрдХ рд╢рд░реНрдд рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬреЛ рдбрдВрдк рдореЗрдВ рдкрдбрд╝реЗ рдбреЗрдЯрд╛ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 'WHERE рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдо =' 'рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ' 'ред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдХрд┐рд╕реА рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рдПрдХ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рддреЗ рд╕рдордп, рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИ рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рд░реВрдк рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ <extension_name> - <old_version> - <new_version> .sql, рдЬрд┐рд╕рдореЗрдВ рдЕрджреНрдпрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП SQL рдХрдорд╛рдВрдб рд╣реИрдВред рдЕрдЧрд░ рд╣рдо math3d рдХреЛ рд╕рдВрд╕реНрдХрд░рдг 1.1 рдореЗрдВ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ math3d рдлрд╛рдЗрд▓ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА - 1.0--1.1.sql рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ SQL рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ:
 ALTER EXTENSION math3d UPDATE TO '1.1' 

рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрд╖ рдЖрджреЗрд╢ ( рдпрд╣рд╛рдВ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИ ):
 ALTER EXTENSION <_> SET SCHEMA < >; --      ALTER EXTENSION <_> ADD <>; --     ALTER EXTENSION <_> DROP <>; --     

рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рдПрдХ рдФрд░ рдЕрдЪреНрдЫреА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдЧрд▓рддреА рд╕реЗ рдЙрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╣рдЯрд╛ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрдорд╛рдВрдб (DROP TABLE, DROP FUNCTION, рдЖрджрд┐) рдХреЗ рд╕рд╛рде рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖



рдпрджрд┐ рд╕рдВрдЧреНрд░рд╣реАрдд рдлрд╝рдВрдХреНрд╢рдВрд╕ рдФрд░ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЧрдП рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЖрдкрдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рдЗрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрдиреНрдп рд╡рд╕реНрддреБрдУрдВ рд╕реЗ рдХреБрдЫ рдЕрд▓рдЧрд╛рд╡ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рдХреА рд╕рд░рд▓реАрдХреГрддрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╡рд┐рд╕реНрддрд╛рд░ рдореЗрдВ рдирд┐рдХрд╛рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдкреБрдирд╢реНрдЪ рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

рд╕рдВрджрд░реНрдн:

Source: https://habr.com/ru/post/In198332/


All Articles