File: pc_editor.c

package info (click to toggle)
pgpointcloud 1.2.1-7
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 4,840 kB
  • sloc: sql: 41,137; ansic: 10,943; xml: 935; cpp: 282; perl: 248; makefile: 185; sh: 72
file content (126 lines) | stat: -rw-r--r-- 2,991 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/***********************************************************************
* pc_editor.c
*
*  Editor functions for points and patches in PgSQL.
*
*  Copyright (c) 2017 Oslandia
*
***********************************************************************/

#include "pc_pgsql.h"	   /* Common PgSQL support for our type */

Datum pcpatch_setpcid(PG_FUNCTION_ARGS);
Datum pcpatch_transform(PG_FUNCTION_ARGS);


static SERIALIZED_PATCH *
pcpatch_set_schema(SERIALIZED_PATCH *serpa,
				  PCSCHEMA *oschema, PCSCHEMA *nschema, float8 def)
{
	SERIALIZED_PATCH *serpatch;
	PCPATCH *paout;

	if ( pc_schema_same_dimensions(oschema, nschema) )
	{
		// oschema and nschema have the same dimensions at the same
		// positions, so we can take a fast path and avoid the
		// point-by-point dimension-by-dimension copying

		if ( oschema->compression == nschema->compression )
		{
			// no need to deserialize the patch
			serpatch = palloc(serpa->size);
			if ( ! serpatch )
				return NULL;
			memcpy(serpatch, serpa, serpa->size);
			serpatch->pcid = nschema->pcid;
			return serpatch;
		}
		else
		{
			paout = pc_patch_deserialize(serpa, oschema);
			if ( ! paout )
				return NULL;
			paout->schema = nschema;
		}
	} else {
		PCPATCH *patch;

		patch = pc_patch_deserialize(serpa, oschema);
		if ( ! patch )
			return NULL;

		paout = pc_patch_set_schema(patch, nschema, def);

		if ( patch != paout )
			pc_patch_free(patch);

		if ( ! paout )
			return NULL;

	}

	serpatch = pc_patch_serialize(paout, NULL);
	pc_patch_free(paout);

	return serpatch;
}


PG_FUNCTION_INFO_V1(pcpatch_setpcid);
Datum pcpatch_setpcid(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *serpatch;
	SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
	int32 pcid = PG_GETARG_INT32(1);
	float8 def = PG_GETARG_FLOAT8(2);
	PCSCHEMA *oschema = pc_schema_from_pcid(serpa->pcid, fcinfo);
	PCSCHEMA *nschema = pc_schema_from_pcid(pcid, fcinfo);

	serpatch = pcpatch_set_schema(serpa, oschema, nschema, def);
	if ( ! serpatch )
		PG_RETURN_NULL();
	PG_RETURN_POINTER(serpatch);
}


PG_FUNCTION_INFO_V1(pcpatch_transform);
Datum pcpatch_transform(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *serpatch;
	SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
	int32 pcid = PG_GETARG_INT32(1);
	float8 def = PG_GETARG_FLOAT8(2);
	PCSCHEMA *oschema = pc_schema_from_pcid(serpa->pcid, fcinfo);
	PCSCHEMA *nschema = pc_schema_from_pcid(pcid, fcinfo);

	// fast path to setpcid if no data transformation is required

	if ( pc_schema_same_interpretations(oschema, nschema) )
	{
		serpatch = pcpatch_set_schema(serpa, oschema, nschema, def);
		if ( ! serpatch )
			PG_RETURN_NULL();
		PG_RETURN_POINTER(serpatch);
	}
	else
	{
		PCPATCH *patch, *paout;

		patch = pc_patch_deserialize(serpa, oschema);
		if ( ! patch )
			PG_RETURN_NULL();

		paout = pc_patch_transform(patch, nschema, def);

		pc_patch_free(patch);

		if ( ! paout )
			PG_RETURN_NULL();

		serpatch = pc_patch_serialize(paout, NULL);
		pc_patch_free(paout);

		PG_RETURN_POINTER(serpatch);
	}
}