/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*-------------------------------------------------------------------------
 *
 * pg_elabel.h
 *    record sql execution information
 *
 *-------------------------------------------------------------------------
 */

#ifndef SRC_INCLUDE_CATALOG_SKYLON_GRAPH_H_
#define SRC_INCLUDE_CATALOG_SKYLON_GRAPH_H_

#include "catalog/genbki.h"
#include "c.h"

/* TIDYCAT_BEGINDEF

   CREATE TABLE skylon_graph
   with (camelcase=Graph, shared=true, oid=false, relid=4856, reltype_oid=4876, content=MASTER_ONLY)
   (
   graphName                name,
   schemaName              name
   );

   TIDYCAT_ENDDEF
*/

/* TIDYCAT_BEGIN_CODEGEN

   WARNING: DO NOT MODIFY THE FOLLOWING SECTION:
   Generated by tidycat.pl version 34
   on Fri Feb 26 10:43:15 2016
*/


/*
 TidyCat Comments for gp_configuration_history:
  Table is shared, so catalog.c:IsSharedRelation is updated.
  Table does not have an Oid column.
  Table has static type (see pg_types.h).
  Table has TOASTable columns, but NO TOAST table.
  Table contents are only maintained on MASTER.
  Table has weird hack for timestamp column.

*/

/*
 * The CATALOG definition has to refer to the type of "time" as
 * "timestamptz" (lower case) so that bootstrap mode recognizes it.  But
 * the C header files define this type as TimestampTz.  Since the field is
 * potentially-null and therefore cannot be accessed directly from C code,
 * there is no particular need for the C struct definition to show the
 * field type as TimestampTz --- instead we just make it Datum.
 */


/* ----------------
 *    skylon_graph definition.  cpp turns this into
 *    typedef struct FormData_skylon_graph
 * ----------------
 */

#define GraphRelationId 4856

CATALOG(skylon_graph,4856) BKI_WITHOUT_OIDS
{
  NameData graphname;
  NameData schemaname;
} FormData_skylon_graph;


/* ----------------
 *    Form_skylon_graph corresponds to a pointer to a tuple with
 *    the format of skylon_graph relation.
 * ----------------
 */

typedef FormData_skylon_graph *Form_skylon_graph;

/* ----------------
 *    compiler constants for pg_database
 * ----------------
 */
#define Natts_skylon_graph 2
#define Anum_skylon_graph_graphname 1
#define Anum_skylon_graph_schemaname 2
/* TIDYCAT_END_CODEGEN */
extern void InsertGraphEntry(const char* graphname, const char* schemaname);

#endif /* SRC_INCLUDE_CATALOG_SKYLON_GRAPH_H_ */
