Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
53243: builtins: implement ST_IsPolygonCW/CCW and ST_ForcePolygonCW/CCW r=sumeerbhola a=otan

Resolves #48956
Resolves #48957
Resolves #48935
Resolves #48936 

Release note (sql change): implement the ST_IsPolygonCW,
ST_IsPolygonCCW, ST_ForcePolygonCW and ST_ForcePolygonCCW builtins.

Release justification: low risk, high benefit changes

53478: backupccl: prevent temporary tables from backupccl r=pbardea a=otan

Filter out temporary tables from resolvable descriptors.

Release justification: low risk, high benefit changes

Resolves: #50902

Release note (sql change): Fix a bug where temporary tables may be
included in `BACKUP` commands.

53496: builtins: implement ST_Points r=otan a=erikgrinaker

Release note (sql change): Implement the geometry builtin `ST_Points`.

Closes #49009.

53523: sql: allow INT to compare to OID r=jordanlewis a=rafiss

An OID is just an INT, so they should be comparable.

Postgres allows this, and certain drivers create queries that attempt to
compare INTs to OIDs, so this improves compatibility.

fixes #53143

Release justification: low-risk, high benefit change that improves
compatibility with PGJDBC.
Release note (sql change): A value of type OID can now be compared to a
value of type INT.

53545: vendor: go get github.com/cockroachdb/datadriven@master r=knz a=tbg

Picks up cockroachdb/datadriven#28.

Release justification: testing
Release note: None


Co-authored-by: Oliver Tan <[email protected]>
Co-authored-by: Erik Grinaker <[email protected]>
Co-authored-by: Rafi Shamim <[email protected]>
Co-authored-by: Tobias Grieger <[email protected]>
  • Loading branch information
5 people committed Aug 27, 2020
6 parents 50fc7c5 + 88453d6 + d3b7085 + eb262e7 + 6517f55 + b712de0 commit 1f1ac2e
Show file tree
Hide file tree
Showing 19 changed files with 786 additions and 7 deletions.
10 changes: 10 additions & 0 deletions docs/generated/sql/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,10 @@ Bottom Left.</p>
</span></td></tr>
<tr><td><a name="st_force2d"></a><code>st_force2d(geometry: geometry) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns a Geometry which only contains X and Y coordinates.</p>
</span></td></tr>
<tr><td><a name="st_forcepolygonccw"></a><code>st_forcepolygonccw(geometry: geometry) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns a Geometry where all Polygon objects have exterior rings in the counter-clockwise orientation and interior rings in the clockwise orientation. Non-Polygon objects are unchanged.</p>
</span></td></tr>
<tr><td><a name="st_forcepolygoncw"></a><code>st_forcepolygoncw(geometry: geometry) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns a Geometry where all Polygon objects have exterior rings in the clockwise orientation and interior rings in the counter-clockwise orientation. Non-Polygon objects are unchanged.</p>
</span></td></tr>
<tr><td><a name="st_geogfromewkb"></a><code>st_geogfromewkb(val: <a href="bytes.html">bytes</a>) &rarr; geography</code></td><td><span class="funcdesc"><p>Returns the Geography from an EWKB representation.</p>
</span></td></tr>
<tr><td><a name="st_geogfromewkt"></a><code>st_geogfromewkt(val: <a href="string.html">string</a>) &rarr; geography</code></td><td><span class="funcdesc"><p>Returns the Geography from an EWKT representation.</p>
Expand Down Expand Up @@ -1338,6 +1342,10 @@ calculated, the result is transformed back into a Geography with SRID 4326.</p>
</span></td></tr>
<tr><td><a name="st_isempty"></a><code>st_isempty(geometry: geometry) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the geometry is empty.</p>
</span></td></tr>
<tr><td><a name="st_ispolygonccw"></a><code>st_ispolygonccw(geometry: geometry) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the Polygon objects inside the Geometry have exterior rings in the counter-clockwise orientation and interior rings in the clockwise orientation. Non-Polygon objects are considered counter-clockwise.</p>
</span></td></tr>
<tr><td><a name="st_ispolygoncw"></a><code>st_ispolygoncw(geometry: geometry) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the Polygon objects inside the Geometry have exterior rings in the clockwise orientation and interior rings in the counter-clockwise orientation. Non-Polygon objects are considered clockwise.</p>
</span></td></tr>
<tr><td><a name="st_isring"></a><code>st_isring(geometry: geometry) &rarr; <a href="bool.html">bool</a></code></td><td><span class="funcdesc"><p>Returns whether the geometry is a single linestring that is closed and simple, as defined by ST_IsClosed and ST_IsSimple.</p>
<p>This function utilizes the GEOS module.</p>
</span></td></tr>
Expand Down Expand Up @@ -1541,6 +1549,8 @@ calculated, the result is transformed back into a Geography with SRID 4326.</p>
<tr><td><a name="st_pointonsurface"></a><code>st_pointonsurface(geometry: geometry) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns a point that intersects with the given Geometry.</p>
<p>This function utilizes the GEOS module.</p>
</span></td></tr>
<tr><td><a name="st_points"></a><code>st_points(geometry: geometry) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns all coordinates in the given Geometry as a MultiPoint, including duplicates.</p>
</span></td></tr>
<tr><td><a name="st_polyfromtext"></a><code>st_polyfromtext(str: <a href="string.html">string</a>, srid: <a href="int.html">int</a>) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns the Geometry from a WKT or EWKT representation with an SRID. If the shape underneath is not Polygon, NULL is returned. If the SRID is present in both the EWKT and the argument, the argument value is used.</p>
</span></td></tr>
<tr><td><a name="st_polyfromtext"></a><code>st_polyfromtext(val: <a href="string.html">string</a>) &rarr; geometry</code></td><td><span class="funcdesc"><p>Returns the Geometry from a WKT or EWKT representation. If the shape underneath is not Polygon, NULL is returned.</p>
Expand Down
8 changes: 8 additions & 0 deletions docs/generated/sql/operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,12 @@
<tr><td><a href="int.html">int</a> <code><</code> <a href="decimal.html">decimal</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code><</code> <a href="float.html">float</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code><</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code><</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int[]</a> <code><</code> <a href="int.html">int[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval</a> <code><</code> <a href="interval.html">interval</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval[]</a> <code><</code> <a href="interval.html">interval[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>jsonb <code><</code> jsonb</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code><</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code><</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string</a> <code><</code> <a href="string.html">string</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string[]</a> <code><</code> <a href="string.html">string[]</a></td><td><a href="bool.html">bool</a></td></tr>
Expand Down Expand Up @@ -237,10 +239,12 @@
<tr><td><a href="int.html">int</a> <code><=</code> <a href="decimal.html">decimal</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code><=</code> <a href="float.html">float</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code><=</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code><=</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int[]</a> <code><=</code> <a href="int.html">int[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval</a> <code><=</code> <a href="interval.html">interval</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval[]</a> <code><=</code> <a href="interval.html">interval[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>jsonb <code><=</code> jsonb</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code><=</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code><=</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string</a> <code><=</code> <a href="string.html">string</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string[]</a> <code><=</code> <a href="string.html">string[]</a></td><td><a href="bool.html">bool</a></td></tr>
Expand Down Expand Up @@ -297,10 +301,12 @@
<tr><td><a href="int.html">int</a> <code>=</code> <a href="decimal.html">decimal</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code>=</code> <a href="float.html">float</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code>=</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code>=</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int[]</a> <code>=</code> <a href="int.html">int[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval</a> <code>=</code> <a href="interval.html">interval</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval[]</a> <code>=</code> <a href="interval.html">interval[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>jsonb <code>=</code> jsonb</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code>=</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code>=</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string</a> <code>=</code> <a href="string.html">string</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string[]</a> <code>=</code> <a href="string.html">string[]</a></td><td><a href="bool.html">bool</a></td></tr>
Expand Down Expand Up @@ -411,10 +417,12 @@
<tr><td><a href="int.html">int</a> <code>IS NOT DISTINCT FROM</code> <a href="decimal.html">decimal</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code>IS NOT DISTINCT FROM</code> <a href="float.html">float</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code>IS NOT DISTINCT FROM</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int</a> <code>IS NOT DISTINCT FROM</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="int.html">int[]</a> <code>IS NOT DISTINCT FROM</code> <a href="int.html">int[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval</a> <code>IS NOT DISTINCT FROM</code> <a href="interval.html">interval</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="interval.html">interval[]</a> <code>IS NOT DISTINCT FROM</code> <a href="interval.html">interval[]</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>jsonb <code>IS NOT DISTINCT FROM</code> jsonb</td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code>IS NOT DISTINCT FROM</code> <a href="int.html">int</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td>oid <code>IS NOT DISTINCT FROM</code> oid</td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string</a> <code>IS NOT DISTINCT FROM</code> <a href="string.html">string</a></td><td><a href="bool.html">bool</a></td></tr>
<tr><td><a href="string.html">string[]</a> <code>IS NOT DISTINCT FROM</code> <a href="string.html">string[]</a></td><td><a href="bool.html">bool</a></td></tr>
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ require (
github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292
github.com/cockroachdb/cockroach-go v0.0.0-20200504194139-73ffeee90b62
github.com/cockroachdb/crlfmt v0.0.0-20200116191136-a78e1c207bc0
github.com/cockroachdb/datadriven v1.0.0
github.com/cockroachdb/datadriven v1.0.1-0.20200826112548-92602d883b11
github.com/cockroachdb/errors v1.7.3
github.com/cockroachdb/go-test-teamcity v0.0.0-20191211140407-cff980ad0a55
github.com/cockroachdb/gostdlib v1.13.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ github.com/cockroachdb/crlfmt v0.0.0-20200116191136-a78e1c207bc0/go.mod h1:uY/PY
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/cockroachdb/datadriven v1.0.0 h1:uhZrAfEayBecH2w2tZmhe20HJ7hDvrrA4x2Bg9YdZKM=
github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4=
github.com/cockroachdb/datadriven v1.0.1-0.20200826112548-92602d883b11 h1:KQqSlwJmTr7NmxtVOl6nPNSZQEk8XuLoLyNDYcmniBo=
github.com/cockroachdb/datadriven v1.0.1-0.20200826112548-92602d883b11/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4=
github.com/cockroachdb/errors v1.2.4 h1:Lap807SXTH5tri2TivECb/4abUkMZC9zRoLarvcKDqs=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM=
Expand Down
5 changes: 4 additions & 1 deletion pkg/ccl/backupccl/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,11 @@ func newDescriptorResolver(descs []catalog.Descriptor) (*descriptorResolver, err
continue
}
var typeToRegister string
switch desc.(type) {
switch desc := desc.(type) {
case catalog.TableDescriptor:
if desc.TableDesc().Temporary {
continue
}
typeToRegister = "table"
case catalog.TypeDescriptor:
typeToRegister = "type"
Expand Down
91 changes: 91 additions & 0 deletions pkg/ccl/backupccl/testdata/backup-restore/temp-tables
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Test that temporary tables do not show up in any backup.

new-server name=s1
----

exec-sql
SET experimental_enable_temp_tables=true;

CREATE DATABASE d1;
USE d1;
CREATE TEMP TABLE temp_table (id int primary key);
CREATE TABLE perm_table (id int primary key)
----

query-sql
SELECT table_name FROM [SHOW TABLES] ORDER BY table_name
----
perm_table
temp_table

query-sql
SELECT
regexp_replace(schema_name, 'pg_temp.*', 'pg_temp') as name
FROM [SHOW SCHEMAS] ORDER BY name
----
crdb_internal
information_schema
pg_catalog
pg_extension
pg_temp
public

exec-sql
BACKUP TABLE temp_table TO 'nodelocal://0/temp_table_backup'
----
pq: table "temp_table" does not exist

exec-sql
BACKUP DATABASE d1 TO 'nodelocal://0/d1_backup/'
----

exec-sql
BACKUP d1.* TO 'nodelocal://0/d1_star_backup/'
----

exec-sql
USE defaultdb;
DROP DATABASE d1;
RESTORE DATABASE d1 FROM 'nodelocal://0/d1_backup/';
USE d1
----

query-sql
SELECT
regexp_replace(schema_name, 'pg_temp.*', 'pg_temp') AS name
FROM [SHOW SCHEMAS] ORDER BY name
----
crdb_internal
information_schema
pg_catalog
pg_extension
public

query-sql
SELECT table_name FROM [SHOW TABLES] ORDER BY table_name
----
perm_table

exec-sql
USE defaultdb;
DROP DATABASE d1;
RESTORE DATABASE d1 FROM 'nodelocal://0/d1_star_backup/';
USE d1
----

query-sql
SELECT
regexp_replace(schema_name, 'pg_temp.*', 'pg_temp') AS name
FROM [SHOW SCHEMAS] ORDER BY name
----
crdb_internal
information_schema
pg_catalog
pg_extension
public

query-sql
USE d1;
SELECT table_name FROM [SHOW TABLES] ORDER BY table_name
----
perm_table
File renamed without changes.
File renamed without changes.
154 changes: 154 additions & 0 deletions pkg/geo/geomfn/orientation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

package geomfn

import (
"github.com/cockroachdb/cockroach/pkg/geo"
"github.com/cockroachdb/errors"
"github.com/twpayne/go-geom"
)

// Orientation defines an orientation of a shape.
type Orientation int

const (
// OrientationCW denotes a clockwise orientation.
OrientationCW Orientation = iota
// OrientationCCW denotes a counter-clockwise orientation
OrientationCCW
)

// HasPolygonOrientation checks whether a given Geometry have polygons
// that matches the given Orientation.
// Non-Polygon objects
func HasPolygonOrientation(g geo.Geometry, o Orientation) (bool, error) {
t, err := g.AsGeomT()
if err != nil {
return false, err
}
return hasPolygonOrientation(t, o)
}

func hasPolygonOrientation(g geom.T, o Orientation) (bool, error) {
switch g := g.(type) {
case *geom.Polygon:
for i := 0; i < g.NumLinearRings(); i++ {
isCCW := geo.IsLinearRingCCW(g.LinearRing(i))
// Interior rings should be the reverse orientation of the exterior ring.
if i > 0 {
isCCW = !isCCW
}
switch o {
case OrientationCW:
if isCCW {
return false, nil
}
case OrientationCCW:
if !isCCW {
return false, nil
}
default:
return false, errors.Newf("unexpected orientation: %v", o)
}
}
return true, nil
case *geom.MultiPolygon:
for i := 0; i < g.NumPolygons(); i++ {
if ret, err := hasPolygonOrientation(g.Polygon(i), o); !ret || err != nil {
return ret, err
}
}
return true, nil
case *geom.GeometryCollection:
for i := 0; i < g.NumGeoms(); i++ {
if ret, err := hasPolygonOrientation(g.Geom(i), o); !ret || err != nil {
return ret, err
}
}
return true, nil
case *geom.Point, *geom.MultiPoint, *geom.LineString, *geom.MultiLineString:
return true, nil
default:
return false, errors.Newf("unhandled geometry type: %T", g)
}
}

// ForcePolygonOrientation forces orientations within polygons
// to be oriented the prescribed way.
func ForcePolygonOrientation(g geo.Geometry, o Orientation) (geo.Geometry, error) {
t, err := g.AsGeomT()
if err != nil {
return geo.Geometry{}, err
}

if err := forcePolygonOrientation(t, o); err != nil {
return geo.Geometry{}, err
}
return geo.MakeGeometryFromGeomT(t)
}

func forcePolygonOrientation(g geom.T, o Orientation) error {
switch g := g.(type) {
case *geom.Polygon:
for i := 0; i < g.NumLinearRings(); i++ {
isCCW := geo.IsLinearRingCCW(g.LinearRing(i))
// Interior rings should be the reverse orientation of the exterior ring.
if i > 0 {
isCCW = !isCCW
}
reverse := false
switch o {
case OrientationCW:
if isCCW {
reverse = true
}
case OrientationCCW:
if !isCCW {
reverse = true
}
default:
return errors.Newf("unexpected orientation: %v", o)
}

if reverse {
// Reverse coordinates from both ends.
// Do this by swapping up to the middle of the array of elements, which guarantees
// each end get swapped. This works for an odd number of elements as well as
// the middle element ends swapping with itself, which is ok.
coords := g.LinearRing(i).FlatCoords()
for cIdx := 0; cIdx < len(coords)/2; cIdx += g.Stride() {
for sIdx := 0; sIdx < g.Stride(); sIdx++ {
coords[cIdx+sIdx], coords[len(coords)-cIdx-g.Stride()+sIdx] = coords[len(coords)-cIdx-g.Stride()+sIdx], coords[cIdx+sIdx]
}
}
}
}
return nil
case *geom.MultiPolygon:
for i := 0; i < g.NumPolygons(); i++ {
if err := forcePolygonOrientation(g.Polygon(i), o); err != nil {
return err
}
}
return nil
case *geom.GeometryCollection:
for i := 0; i < g.NumGeoms(); i++ {
if err := forcePolygonOrientation(g.Geom(i), o); err != nil {
return err
}
}
return nil
case *geom.Point, *geom.MultiPoint, *geom.LineString, *geom.MultiLineString:
return nil
default:
return errors.Newf("unhandled geometry type: %T", g)
}
}
Loading

0 comments on commit 1f1ac2e

Please sign in to comment.