Skip to content

Commit

Permalink
Merge pull request #11097 from rouault/fix_11094
Browse files Browse the repository at this point in the history
FileGDB/OpenFileGDB: update (and unify) list of reserved keywords that can't be used for column/table names
  • Loading branch information
rouault authored Oct 24, 2024
2 parents 49675ff + 85ffa68 commit ffc433a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 28 deletions.
10 changes: 5 additions & 5 deletions autotest/ogr/ogr_openfilegdb_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -4265,7 +4265,7 @@ def test_ogr_openfilegdb_write_new_datetime_types(tmp_vsimem):
lyr = ds.GetLayerByName("date_types")
lyr_defn = lyr.GetLayerDefn()

fld_defn = lyr_defn.GetFieldDefn(lyr_defn.GetFieldIndex("date_"))
fld_defn = lyr_defn.GetFieldDefn(lyr_defn.GetFieldIndex("date"))
assert fld_defn.GetType() == ogr.OFTDateTime
assert fld_defn.GetDefault() == "'2023/02/01 04:05:06'"

Expand All @@ -4282,13 +4282,13 @@ def test_ogr_openfilegdb_write_new_datetime_types(tmp_vsimem):
assert fld_defn.GetDefault() == "'2023/02/01 04:05:06.000+06:00'"

f = lyr.GetNextFeature()
assert f["date_"] == "2023/11/29 13:14:15+00"
assert f["date"] == "2023/11/29 13:14:15+00"
assert f["date_only"] == "2023/11/29"
assert f["time_only"] == "13:14:15"
assert f["timestamp_offset"] == "2023/11/29 13:14:15-05"

f = lyr.GetNextFeature()
assert f["date_"] == "2023/12/31 00:01:01+00"
assert f["date"] == "2023/12/31 00:01:01+00"
assert f["date_only"] == "2023/12/31"
assert f["time_only"] == "00:01:01"
assert f["timestamp_offset"] == "2023/12/31 00:01:01+10"
Expand All @@ -4297,13 +4297,13 @@ def test_ogr_openfilegdb_write_new_datetime_types(tmp_vsimem):
lyr_defn = lyr.GetLayerDefn()

f = lyr.GetNextFeature()
assert f["date_"] == "2023/11/29 13:14:15.678+00"
assert f["date"] == "2023/11/29 13:14:15.678+00"
assert f["date_only"] == "2023/11/29"
assert f["time_only"] == "13:14:15"
assert f["timestamp_offset"] == "2023/11/29 13:14:15-05"

f = lyr.GetNextFeature()
assert f["date_"] == "2023/12/31 00:01:01.001+00"
assert f["date"] == "2023/12/31 00:01:01.001+00"
assert f["date_only"] == "2023/12/31"
assert f["time_only"] == "00:01:01"
assert f["timestamp_offset"] == "2023/12/31 00:01:01+10"
Expand Down
15 changes: 3 additions & 12 deletions ogr/ogrsf_frmts/filegdb/FGdbUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "ogr_api.h"
#include "ogrpgeogeometry.h"
#include "filegdb_reserved_keywords.h"

using std::string;

Expand Down Expand Up @@ -531,21 +532,11 @@ std::wstring FGDBEscapeReservedKeywords(const std::wstring &name)
std::string newName = WStringToString(name);
std::string upperName = CPLString(newName).toupper();

// From ESRI docs
static const char *const RESERVED_WORDS[] = {
FGDB_OID_NAME, "ADD", "ALTER", "AND", "AS", "ASC",
"BETWEEN", "BY", "COLUMN", "CREATE", "DATE", "DELETE",
"DESC", "DROP", "EXISTS", "FOR", "FROM", "IN",
"INSERT", "INTO", "IS", "LIKE", "NOT", "NULL",
"OR", "ORDER", "SELECT", "SET", "TABLE", "UPDATE",
"VALUES", "WHERE", nullptr};

// Append an underscore to any FGDB reserved words used as field names
// This is the same behavior ArcCatalog follows.
for (int i = 0; RESERVED_WORDS[i] != nullptr; i++)
for (const char *pszKeyword : apszRESERVED_WORDS)
{
const char *w = RESERVED_WORDS[i];
if (upperName == w)
if (upperName == pszKeyword)
{
newName += '_';
break;
Expand Down
24 changes: 24 additions & 0 deletions ogr/ogrsf_frmts/openfilegdb/filegdb_reserved_keywords.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/******************************************************************************
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: List of reserver keywords for File Geodatabase
* Author: Even Rouault, <even.rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2024, Even Rouault, <even.rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/

#ifndef FILEGDB_RESERVED_KEYWORDS_H
#define FILEGDB_RESERVED_KEYWORDS_H

// from https://support.esri.com/en-us/knowledge-base/what-are-the-reserved-words-for-esri-s-file-geodatabase-000010906
static constexpr const char *const apszRESERVED_WORDS[] = {
"ADD", "ALTER", "AND", "BETWEEN", "BY", "COLUMN", "CREATE",
"DELETE", "DROP", "EXISTS", "FOR", "FROM", "GROUP", "IN",
"INSERT", "INTO", "IS", "LIKE", "NOT", "NULL", "OR",
"ORDER", "SELECT", "SET", "TABLE", "UPDATE", "VALUES", "WHERE",
};

#endif // FILEGDB_RESERVED_KEYWORDS_H
14 changes: 3 additions & 11 deletions ogr/ogrsf_frmts/openfilegdb/ogropenfilegdblayer_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "filegdbtable.h"
#include "filegdbtable_priv.h"
#include "filegdb_coordprec_write.h"
#include "filegdb_reserved_keywords.h"

/*************************************************************************/
/* StringToWString() */
Expand Down Expand Up @@ -137,20 +138,11 @@ static std::wstring EscapeReservedKeywords(const std::wstring &name)
std::string newName = WStringToString(name);
std::string upperName = CPLString(newName).toupper();

// From ESRI docs
static const char *const RESERVED_WORDS[] = {
"OBJECTID", "ADD", "ALTER", "AND", "AS", "ASC", "BETWEEN",
"BY", "COLUMN", "CREATE", "DATE", "DELETE", "DESC", "DROP",
"EXISTS", "FOR", "FROM", "IN", "INSERT", "INTO", "IS",
"LIKE", "NOT", "NULL", "OR", "ORDER", "SELECT", "SET",
"TABLE", "UPDATE", "VALUES", "WHERE", nullptr};

// Append an underscore to any FGDB reserved words used as field names
// This is the same behavior ArcCatalog follows.
for (int i = 0; RESERVED_WORDS[i] != nullptr; i++)
for (const char *pszKeyword : apszRESERVED_WORDS)
{
const char *w = RESERVED_WORDS[i];
if (upperName == w)
if (upperName == pszKeyword)
{
newName += '_';
break;
Expand Down

0 comments on commit ffc433a

Please sign in to comment.